murrine r2 - in trunk: . src



Author: acimitan
Date: Mon Feb 11 23:01:49 2008
New Revision: 2
URL: http://svn.gnome.org/viewvc/murrine?rev=2&view=rev

Log:
First commit

Added:
   trunk/AUTHORS
   trunk/COPYING
   trunk/CREDITS
   trunk/ChangeLog
   trunk/INSTALL
   trunk/MAINTAINERS
   trunk/Makefile.am
   trunk/NEWS
   trunk/README
   trunk/autogen.sh   (contents, props changed)
   trunk/configure.ac
   trunk/murrine.pc.in
   trunk/src/
   trunk/src/animation.c
   trunk/src/animation.h
   trunk/src/cairo-support.c
   trunk/src/cairo-support.h
   trunk/src/config.h.in
   trunk/src/murrine_draw.c
   trunk/src/murrine_draw.h
   trunk/src/murrine_draw_rgba.c
   trunk/src/murrine_draw_rgba.h
   trunk/src/murrine_rc_style.c
   trunk/src/murrine_rc_style.h
   trunk/src/murrine_style.c
   trunk/src/murrine_style.h
   trunk/src/murrine_theme_main.c
   trunk/src/murrine_types.h
   trunk/src/support.c
   trunk/src/support.h

Added: trunk/AUTHORS
==============================================================================
--- (empty file)
+++ trunk/AUTHORS	Mon Feb 11 23:01:49 2008
@@ -0,0 +1,15 @@
+"Murrine Gtk2 Cairo Engine"
+Copyright (C) 2007 Andrea Cimitan
+
+Licensed under the GNU GPL License
+
+Murrine is based on:
+	Candido:
+	  Andrea Cimitan        - andrea cimitan gmail com	
+	Rezlooks:
+	  Doug Whiteley         - dougwhiteley gmail com
+	Clearlooks:
+	  Richard Stellingwerff - remenic gmail com
+	  Daniel Borgmann       - daniel borgmann gmail com
+
+(See CREDITS file for other contributors)

Added: trunk/COPYING
==============================================================================
--- (empty file)
+++ trunk/COPYING	Mon Feb 11 23:01:49 2008
@@ -0,0 +1,340 @@
+		    GNU GENERAL PUBLIC LICENSE
+		       Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 	51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+			    Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.)  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, 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 or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must show them these terms so they know their
+rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+		    GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute verbatim copies of the Program's
+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 give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, 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) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+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 Program, 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 Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+    a) 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; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, 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 executable.  However, as a
+special exception, the source code 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.
+
+If distribution of executable or 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 counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program 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.
+
+  5. 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 Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program 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 to
+this License.
+
+  7. 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 Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program 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 Program.
+
+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.
+
+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program 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.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the 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 Program
+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 Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, 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
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "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 PROGRAM IS WITH YOU.  SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+  12. 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 PROGRAM 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 PROGRAM (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 PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+		     END OF TERMS AND CONDITIONS
+
+	    How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  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 program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    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 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.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; 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.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) year  name of author
+    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+  `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+  <signature of Ty Coon>, 1 April 1989
+  Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs.  If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library.  If this is what you want to do, use the GNU Library General
+Public License instead of this License.

Added: trunk/CREDITS
==============================================================================
--- (empty file)
+++ trunk/CREDITS	Mon Feb 11 23:01:49 2008
@@ -0,0 +1,7 @@
+Cimi's thanks:
+
+Doug Whitely   - for the permission to edit his theme and for the little help.
+
+Oliver Tobin   - for his support to refine my theme.
+
+Benjiamin Berg - for all his bugfixes... and a lot more... thanks!!!

Added: trunk/INSTALL
==============================================================================
--- (empty file)
+++ trunk/INSTALL	Mon Feb 11 23:01:49 2008
@@ -0,0 +1,236 @@
+Installation Instructions
+*************************
+
+Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005 Free
+Software Foundation, Inc.
+
+This file is free documentation; the Free Software Foundation gives
+unlimited permission to copy, distribute and modify it.
+
+Basic Installation
+==================
+
+These are generic installation instructions.
+
+   The `configure' shell script attempts to guess correct values for
+various system-dependent variables used during compilation.  It uses
+those values to create a `Makefile' in each directory of the package.
+It may also create one or more `.h' files containing system-dependent
+definitions.  Finally, it creates a shell script `config.status' that
+you can run in the future to recreate the current configuration, and a
+file `config.log' containing compiler output (useful mainly for
+debugging `configure').
+
+   It can also use an optional file (typically called `config.cache'
+and enabled with `--cache-file=config.cache' or simply `-C') that saves
+the results of its tests to speed up reconfiguring.  (Caching is
+disabled by default to prevent problems with accidental use of stale
+cache files.)
+
+   If you need to do unusual things to compile the package, please try
+to figure out how `configure' could check whether to do them, and mail
+diffs or instructions to the address given in the `README' so they can
+be considered for the next release.  If you are using the cache, and at
+some point `config.cache' contains results you don't want to keep, you
+may remove or edit it.
+
+   The file `configure.ac' (or `configure.in') is used to create
+`configure' by a program called `autoconf'.  You only need
+`configure.ac' if you want to change it or regenerate `configure' using
+a newer version of `autoconf'.
+
+The simplest way to compile this package is:
+
+  1. `cd' to the directory containing the package's source code and type
+     `./configure' to configure the package for your system.  If you're
+     using `csh' on an old version of System V, you might need to type
+     `sh ./configure' instead to prevent `csh' from trying to execute
+     `configure' itself.
+
+     Running `configure' takes awhile.  While running, it prints some
+     messages telling which features it is checking for.
+
+  2. Type `make' to compile the package.
+
+  3. Optionally, type `make check' to run any self-tests that come with
+     the package.
+
+  4. Type `make install' to install the programs and any data files and
+     documentation.
+
+  5. You can remove the program binaries and object files from the
+     source code directory by typing `make clean'.  To also remove the
+     files that `configure' created (so you can compile the package for
+     a different kind of computer), type `make distclean'.  There is
+     also a `make maintainer-clean' target, but that is intended mainly
+     for the package's developers.  If you use it, you may have to get
+     all sorts of other programs in order to regenerate files that came
+     with the distribution.
+
+Compilers and Options
+=====================
+
+Some systems require unusual options for compilation or linking that the
+`configure' script does not know about.  Run `./configure --help' for
+details on some of the pertinent environment variables.
+
+   You can give `configure' initial values for configuration parameters
+by setting variables in the command line or in the environment.  Here
+is an example:
+
+     ./configure CC=c89 CFLAGS=-O2 LIBS=-lposix
+
+   *Note Defining Variables::, for more details.
+
+Compiling For Multiple Architectures
+====================================
+
+You can compile the package for more than one kind of computer at the
+same time, by placing the object files for each architecture in their
+own directory.  To do this, you must use a version of `make' that
+supports the `VPATH' variable, such as GNU `make'.  `cd' to the
+directory where you want the object files and executables to go and run
+the `configure' script.  `configure' automatically checks for the
+source code in the directory that `configure' is in and in `..'.
+
+   If you have to use a `make' that does not support the `VPATH'
+variable, you have to compile the package for one architecture at a
+time in the source code directory.  After you have installed the
+package for one architecture, use `make distclean' before reconfiguring
+for another architecture.
+
+Installation Names
+==================
+
+By default, `make install' installs the package's commands under
+`/usr/local/bin', include files under `/usr/local/include', etc.  You
+can specify an installation prefix other than `/usr/local' by giving
+`configure' the option `--prefix=PREFIX'.
+
+   You can specify separate installation prefixes for
+architecture-specific files and architecture-independent files.  If you
+pass the option `--exec-prefix=PREFIX' to `configure', the package uses
+PREFIX as the prefix for installing programs and libraries.
+Documentation and other data files still use the regular prefix.
+
+   In addition, if you use an unusual directory layout you can give
+options like `--bindir=DIR' to specify different values for particular
+kinds of files.  Run `configure --help' for a list of the directories
+you can set and what kinds of files go in them.
+
+   If the package supports it, you can cause programs to be installed
+with an extra prefix or suffix on their names by giving `configure' the
+option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
+
+Optional Features
+=================
+
+Some packages pay attention to `--enable-FEATURE' options to
+`configure', where FEATURE indicates an optional part of the package.
+They may also pay attention to `--with-PACKAGE' options, where PACKAGE
+is something like `gnu-as' or `x' (for the X Window System).  The
+`README' should mention any `--enable-' and `--with-' options that the
+package recognizes.
+
+   For packages that use the X Window System, `configure' can usually
+find the X include and library files automatically, but if it doesn't,
+you can use the `configure' options `--x-includes=DIR' and
+`--x-libraries=DIR' to specify their locations.
+
+Specifying the System Type
+==========================
+
+There may be some features `configure' cannot figure out automatically,
+but needs to determine by the type of machine the package will run on.
+Usually, assuming the package is built to be run on the _same_
+architectures, `configure' can figure that out, but if it prints a
+message saying it cannot guess the machine type, give it the
+`--build=TYPE' option.  TYPE can either be a short name for the system
+type, such as `sun4', or a canonical name which has the form:
+
+     CPU-COMPANY-SYSTEM
+
+where SYSTEM can have one of these forms:
+
+     OS KERNEL-OS
+
+   See the file `config.sub' for the possible values of each field.  If
+`config.sub' isn't included in this package, then this package doesn't
+need to know the machine type.
+
+   If you are _building_ compiler tools for cross-compiling, you should
+use the option `--target=TYPE' to select the type of system they will
+produce code for.
+
+   If you want to _use_ a cross compiler, that generates code for a
+platform different from the build platform, you should specify the
+"host" platform (i.e., that on which the generated programs will
+eventually be run) with `--host=TYPE'.
+
+Sharing Defaults
+================
+
+If you want to set default values for `configure' scripts to share, you
+can create a site shell script called `config.site' that gives default
+values for variables like `CC', `cache_file', and `prefix'.
+`configure' looks for `PREFIX/share/config.site' if it exists, then
+`PREFIX/etc/config.site' if it exists.  Or, you can set the
+`CONFIG_SITE' environment variable to the location of the site script.
+A warning: not all `configure' scripts look for a site script.
+
+Defining Variables
+==================
+
+Variables not defined in a site shell script can be set in the
+environment passed to `configure'.  However, some packages may run
+configure again during the build, and the customized values of these
+variables may be lost.  In order to avoid this problem, you should set
+them in the `configure' command line, using `VAR=value'.  For example:
+
+     ./configure CC=/usr/local2/bin/gcc
+
+causes the specified `gcc' to be used as the C compiler (unless it is
+overridden in the site shell script).  Here is a another example:
+
+     /bin/bash ./configure CONFIG_SHELL=/bin/bash
+
+Here the `CONFIG_SHELL=/bin/bash' operand causes subsequent
+configuration-related scripts to be executed by `/bin/bash'.
+
+`configure' Invocation
+======================
+
+`configure' recognizes the following options to control how it operates.
+
+`--help'
+`-h'
+     Print a summary of the options to `configure', and exit.
+
+`--version'
+`-V'
+     Print the version of Autoconf used to generate the `configure'
+     script, and exit.
+
+`--cache-file=FILE'
+     Enable the cache: use and save the results of the tests in FILE,
+     traditionally `config.cache'.  FILE defaults to `/dev/null' to
+     disable caching.
+
+`--config-cache'
+`-C'
+     Alias for `--cache-file=config.cache'.
+
+`--quiet'
+`--silent'
+`-q'
+     Do not print messages saying which checks are being made.  To
+     suppress all normal output, redirect it to `/dev/null' (any error
+     messages will still be shown).
+
+`--srcdir=DIR'
+     Look for the package's source code in directory DIR.  Usually
+     `configure' can determine that directory automatically.
+
+`configure' also accepts some other, not widely useful, options.  Run
+`configure --help' for more details.
+

Added: trunk/MAINTAINERS
==============================================================================
--- (empty file)
+++ trunk/MAINTAINERS	Mon Feb 11 23:01:49 2008
@@ -0,0 +1,3 @@
+Andrea Cimitan
+E-mail: andrea cimitan gmail com
+Userid: acimitan

Added: trunk/Makefile.am
==============================================================================
--- (empty file)
+++ trunk/Makefile.am	Mon Feb 11 23:01:49 2008
@@ -0,0 +1,28 @@
+INCLUDES = $(GTK_CFLAGS)
+
+enginedir = $(libdir)/gtk-2.0/$(GTK_VERSION)/engines
+engine_LTLIBRARIES = libmurrine.la
+
+EXTRA_DIST = ./src/config.h.in
+
+libmurrine_la_SOURCES = \
+	./src/animation.c \
+	./src/animation.h \
+	./src/cairo-support.c \
+	./src/cairo-support.h \
+	./src/config.h \
+	./src/support.c \
+	./src/support.h \
+	./src/murrine_rc_style.c \
+	./src/murrine_rc_style.h \
+	./src/murrine_style.c \
+	./src/murrine_style.h \
+	./src/murrine_theme_main.c \
+	./src/murrine_draw.c \
+	./src/murrine_draw_rgba.c \
+	./src/murrine_draw.h \
+	./src/murrine_types.h
+
+libmurrine_la_LDFLAGS = -module -avoid-version -no-undefined
+libmurrine_la_LIBADD =  $(GTK_LIBS)
+

Added: trunk/NEWS
==============================================================================
--- (empty file)
+++ trunk/NEWS	Mon Feb 11 23:01:49 2008
@@ -0,0 +1 @@
+See Changelog for news.

Added: trunk/README
==============================================================================
--- (empty file)
+++ trunk/README	Mon Feb 11 23:01:49 2008
@@ -0,0 +1,9 @@
+This is Murrine GTK+ engine. This source code provides only the engine, get the themes @ gnomelook.org.
+
+Do the normal dance to install:
+
+	(./autogen.sh ; ) ./configure (generally --prefix=/usr, try --enable-animation); make ; make install
+
+To uninstall:
+	
+	make uninstall

Added: trunk/autogen.sh
==============================================================================
--- (empty file)
+++ trunk/autogen.sh	Mon Feb 11 23:01:49 2008
@@ -0,0 +1,65 @@
+#!/bin/sh
+# Run this to generate all the initial makefiles, etc.
+
+srcdir=`dirname $0`
+test -z "$srcdir" && srcdir=.
+DIE=0
+
+THEDIR=`pwd`
+cd $srcdir
+
+(autoconf --version) < /dev/null > /dev/null 2>&1 || {
+	echo
+	echo "You must have autoconf installed to compile GTK+."
+	echo "Download the appropriate package for your distribution,"
+	echo "or get the source tarball at http://ftp.gnu.org/gnu/autoconf/";
+	DIE=1
+}
+
+if automake-1.10 --version < /dev/null > /dev/null 2>&1 ; then
+    AUTOMAKE=automake-1.10
+    ACLOCAL=aclocal-1.10
+elif automake-1.9 --version < /dev/null > /dev/null 2>&1 ; then
+    AUTOMAKE=automake-1.9
+    ACLOCAL=aclocal-1.9
+elif automake-1.8 --version < /dev/null > /dev/null 2>&1 ; then
+    AUTOMAKE=automake-1.8
+    ACLOCAL=aclocal-1.8
+elif automake-1.7 --version < /dev/null > /dev/null 2>&1 ; then
+    AUTOMAKE=automake-1.7
+    ACLOCAL=aclocal-1.7
+else
+        echo
+        echo "You must have automake 1.7.x installed to compile $PROJECT."
+        echo "Install the appropriate package for your distribution,"
+        echo "or get the source tarball at http://ftp.gnu.org/gnu/automake/";
+        DIE=1
+fi
+
+(libtool --version) < /dev/null > /dev/null 2>&1 || {
+	echo
+	echo "You must have libtool installed to compile GTK+."
+	echo "Get http://ftp.gnu.org/gnu/libtool/libtool-1.5.10.tar.gz";
+	echo "(or a newer version if it is available)"
+	DIE=1
+}
+if test "$DIE" -eq 1; then
+	exit 1
+fi
+
+if test -z "$*"; then
+	echo "I am going to run ./configure with no arguments - if you wish "
+        echo "to pass any to it, please specify them on the $0 command line."
+fi
+
+libtoolize --force --copy
+
+$ACLOCAL $ACLOCAL_FLAGS
+autoconf
+$AUTOMAKE --add-missing
+cd $THEDIR
+
+$srcdir/configure --enable-maintainer-mode "$@"
+
+echo 
+echo "Now type 'make' to compile themes"

Added: trunk/configure.ac
==============================================================================
--- (empty file)
+++ trunk/configure.ac	Mon Feb 11 23:01:49 2008
@@ -0,0 +1,56 @@
+AC_INIT([murrine], [0.60])
+AC_CONFIG_SRCDIR([README])
+
+AM_INIT_AUTOMAKE
+
+dnl Initialize maintainer mode
+AM_MAINTAINER_MODE
+
+AC_PROG_CC
+AM_PROG_CC_STDC
+AC_PROG_INSTALL
+AC_PROG_MAKE_SET
+
+dnl Initialize libtool
+AM_DISABLE_STATIC
+AC_LIBTOOL_WIN32_DLL
+AM_PROG_LIBTOOL
+
+AC_ARG_ENABLE(animation, [  --enable-animation      compile murrine with animation support], [animation=$enableval], 	[animation="no"], )
+AC_ARG_ENABLE(macmenu, [  --enable-macmenu        compile murrine with mac menubar patches], [macmenu=$enableval], 	[macmenu="no"], )
+AC_ARG_ENABLE(animationtoleft, [  --enable-animationtoleft        compile murrine with progressbar animation from right to left], [animationtoleft=$enableval], 	[animationtoleft="no"], )
+
+PKG_CHECK_MODULES(GTK, gtk+-2.0 >= 2.8.0,,
+                  AC_MSG_ERROR([GTK+-2.8 is required to compile murrine]))
+
+AC_SUBST(GTK_CFLAGS)
+AC_SUBST(GTK_LIBS)
+
+GTK_VERSION=`$PKG_CONFIG --variable=gtk_binary_version gtk+-2.0`
+AC_SUBST(GTK_VERSION)
+
+AC_SUBST(BUILD_ENGINES)
+AC_SUBST(BUILD_THEMES)
+
+if test $animation = "yes"; then
+	AC_DEFINE_UNQUOTED(HAVE_ANIMATION, 1, [Defines whether to compile with animation support])
+fi
+
+if test $macmenu = "yes"; then
+	AC_DEFINE_UNQUOTED(HAVE_MACMENU, 1, [Defines whether to compile with mac menubar patches])
+fi
+
+if test $animationtoleft = "yes"; then
+	AC_DEFINE_UNQUOTED(HAVE_ANIMATIONTOLEFT, 1, [Defines whether to compile with progressbar animation from right to left])
+fi
+
+AM_CONFIG_HEADER([src/config.h])
+
+AC_CONFIG_FILES([
+Makefile
+murrine.pc
+]) 
+
+AC_OUTPUT
+
+echo "Now run make."

Added: trunk/murrine.pc.in
==============================================================================
--- (empty file)
+++ trunk/murrine.pc.in	Mon Feb 11 23:01:49 2008
@@ -0,0 +1,9 @@
+prefix= prefix@
+exec_prefix= exec_prefix@
+libdir= libdir@
+includedir= includedir@
+
+Name: murrine
+Description: Murrine GTK+ Theme Engine
+Version: @VERSION@
+Requires: gtk+-2.0

Added: trunk/src/animation.c
==============================================================================
--- (empty file)
+++ trunk/src/animation.c	Mon Feb 11 23:01:49 2008
@@ -0,0 +1,328 @@
+/* Murrine theme engine
+ * Copyright (C) 2007 Andrea Cimitan
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include "animation.h"
+
+#ifdef HAVE_ANIMATION
+#include <glib/gtimer.h>
+
+struct _AnimationInfo
+{
+	GTimer *timer;
+	
+	gdouble start_modifier;
+	gdouble stop_time;
+	GtkWidget *widget;
+};
+typedef struct _AnimationInfo AnimationInfo;
+
+struct _SignalInfo
+{
+	GtkWidget *widget;
+	gulong handler_id;
+};
+typedef struct _SignalInfo SignalInfo;
+
+static GSList     *connected_widgets  = NULL;
+static GHashTable *animated_widgets   = NULL;
+static int         animation_timer_id = 0;
+
+static gboolean animation_timeout_handler (gpointer data);
+
+/* This forces a redraw on a widget */
+static gboolean
+force_widget_redraw (GtkWidget *widget)
+{
+	if (GTK_IS_PROGRESS_BAR (widget))
+		gtk_widget_queue_resize (widget);
+	else
+		gtk_widget_queue_draw (widget);
+}
+
+/* ensures that the timer is running */
+static void
+start_timer ()
+{
+	if (animation_timer_id == 0)
+		animation_timer_id = g_timeout_add (ANIMATION_DELAY, animation_timeout_handler, NULL);
+}
+
+/* ensures that the timer is stopped */
+static void
+stop_timer ()
+{
+	if (animation_timer_id != 0)
+	{
+		g_source_remove(animation_timer_id);
+		animation_timer_id = 0;
+	}
+}
+
+
+/* destroys an AnimationInfo structure including the GTimer */
+static void
+animation_info_destroy (AnimationInfo *animation_info)
+{
+	g_timer_destroy (animation_info->timer);
+	g_free (animation_info);
+}
+
+/* This function does not unref the weak reference, because the object
+ * is beeing destroyed currently. */
+static void
+on_animated_widget_destruction (gpointer data, GObject *object)
+{
+	/* steal the animation info from the hash table (destroying it would
+	 * result in the weak reference to be unrefed, which does not work
+	 * as the widget is already destroyed. */
+	g_hash_table_steal (animated_widgets, object);
+	animation_info_destroy ((AnimationInfo*) data);
+}
+
+/* This function also needs to unref the weak reference. */
+static void
+destroy_animation_info_and_weak_unref (gpointer data)
+{
+	AnimationInfo *animation_info = data;
+	
+	/* force a last redraw. This is so that if the animation is removed,
+	 * the widget is left in a sane state. */
+	force_widget_redraw (animation_info->widget);
+	
+	g_object_weak_unref (G_OBJECT (animation_info->widget), on_animated_widget_destruction, data);
+	animation_info_destroy (animation_info);
+}
+
+/* Find and return a pointer to the data linked to this widget, if it exists */
+static AnimationInfo*
+lookup_animation_info (const GtkWidget *widget)
+{
+	if (animated_widgets)
+		return g_hash_table_lookup (animated_widgets, widget);
+	
+	return NULL;
+}
+
+/* Create all the relevant information for the animation, and insert it into the hash table. */
+static void
+add_animation (const GtkWidget *widget, gdouble stop_time)
+{
+	AnimationInfo *value;
+	
+	/* object already in the list, do not add it twice */
+	if (lookup_animation_info (widget))
+		return;
+	
+	if (animated_widgets == NULL)
+		animated_widgets = g_hash_table_new_full (g_direct_hash, g_direct_equal,
+		                                          NULL, destroy_animation_info_and_weak_unref);
+	
+	value = g_new(AnimationInfo, 1);
+	
+	value->widget = (GtkWidget*) widget;
+	
+	value->timer = g_timer_new ();
+	value->stop_time= stop_time;
+	value->start_modifier = 0.0;
+
+	g_object_weak_ref (G_OBJECT (widget), on_animated_widget_destruction, value);
+	g_hash_table_insert (animated_widgets, (GtkWidget*) widget, value);
+	
+	start_timer ();
+}
+
+/* update the animation information for each widget. This will also queue a redraw
+ * and stop the animation if it is done. */
+static gboolean
+update_animation_info (gpointer key, gpointer value, gpointer user_data)
+{
+	AnimationInfo *animation_info = value;
+	GtkWidget *widget = key;
+	gdouble elapsed;
+	
+	if ((widget == NULL) || (animation_info == NULL))
+		g_assert_not_reached ();
+	
+	/* remove the widget from the hash table if it is not drawable */
+	if (!GTK_WIDGET_DRAWABLE (widget))
+		return TRUE;
+	
+	if (GTK_IS_PROGRESS_BAR (widget))
+	{
+		gfloat fraction = gtk_progress_bar_get_fraction (GTK_PROGRESS_BAR (widget));
+		
+		/* stop animation for filled/not filled progress bars */
+		if (fraction <= 0.0 || fraction >= 1.0)
+			return TRUE;
+	}
+	
+	force_widget_redraw (widget);
+	
+	/* stop at stop_time */
+	if (animation_info->stop_time != 0 &&
+	    g_timer_elapsed (animation_info->timer, NULL) > animation_info->stop_time)
+		return TRUE;
+	
+	return FALSE;
+}
+
+/* This gets called by the glib main loop every once in a while. */
+static gboolean
+animation_timeout_handler (gpointer data)
+{
+	/* enter threads as update_animation_info will use gtk/gdk. */
+	gdk_threads_enter ();
+
+	/*g_print("** TICK **\n");*/
+	g_hash_table_foreach_remove (animated_widgets, update_animation_info, NULL);
+	
+	/* leave again */
+	gdk_threads_leave ();
+	
+	if(g_hash_table_size(animated_widgets)==0)
+	{
+		stop_timer ();
+		return FALSE;
+	}
+	
+	return TRUE;
+}
+
+static void
+on_checkbox_toggle (GtkWidget *widget, gpointer data)
+{
+	AnimationInfo *animation_info = lookup_animation_info (widget);
+	
+	if (animation_info != NULL)
+	{
+		gfloat elapsed = g_timer_elapsed (animation_info->timer, NULL);
+		
+		animation_info->start_modifier = elapsed - animation_info->start_modifier;
+	}
+	else
+	{
+		add_animation (widget, CHECK_ANIMATION_TIME);
+	}
+}
+
+static void
+on_connected_widget_destruction (gpointer data, GObject *widget)
+{
+	connected_widgets = g_slist_remove (connected_widgets, data);
+	g_free (data);
+}
+
+static void
+disconnect_all_signals ()
+{
+	GSList * item = connected_widgets;
+	while (item != NULL)
+	{
+		SignalInfo *signal_info = (SignalInfo*) item->data;
+		
+		g_signal_handler_disconnect (signal_info->widget, signal_info->handler_id);
+		g_object_weak_unref (G_OBJECT (signal_info->widget), on_connected_widget_destruction, signal_info);
+		g_free (signal_info);
+		
+		item = g_slist_next (item);
+	}
+	
+	g_slist_free (connected_widgets);
+	connected_widgets = NULL;
+}
+
+/* helper function for murrine_animation_connect_checkbox */
+static gint
+find_signal_info (gconstpointer signal_info, gconstpointer widget)
+{
+	if (((SignalInfo*)signal_info)->widget == widget)
+		return 0;
+	else
+		return 1;
+}
+
+
+/* external interface */
+
+/* adds a progress bar */
+void
+murrine_animation_progressbar_add (GtkWidget *progressbar)
+{
+	gdouble fraction = gtk_progress_bar_get_fraction (GTK_PROGRESS_BAR (progressbar));
+	
+	if (fraction < 1.0 && fraction > 0.0)
+		add_animation ((GtkWidget*) progressbar, 0.0);
+}
+
+/* hooks up the signals for check and radio buttons */
+void
+murrine_animation_connect_checkbox (GtkWidget *widget)
+{
+	if (GTK_IS_CHECK_BUTTON (widget))
+	{
+		if (!g_slist_find_custom (connected_widgets, widget, find_signal_info))
+		{
+			SignalInfo * signal_info = g_new (SignalInfo, 1);
+			
+			signal_info->widget = widget;
+			signal_info->handler_id = g_signal_connect ((GObject*)widget, "toggled", G_CALLBACK (on_checkbox_toggle), NULL);
+			
+			connected_widgets = g_slist_append (connected_widgets, signal_info);
+			g_object_weak_ref (G_OBJECT (widget), on_connected_widget_destruction, signal_info);
+		}
+	}
+}
+
+/* returns TRUE if the widget is animated, and FALSE otherwise */
+gboolean
+murrine_animation_is_animated (GtkWidget *widget)
+{
+	return lookup_animation_info (widget) != NULL ? TRUE : FALSE;
+}
+
+/* returns the elapsed time for the animation */
+gdouble
+murrine_animation_elapsed (gpointer data)
+{
+	AnimationInfo *animation_info = lookup_animation_info (data);
+	
+	if (animation_info)
+		return   g_timer_elapsed (animation_info->timer, NULL)
+		       - animation_info->start_modifier;
+	else
+		return 0.0;
+}
+
+/* cleans up all resources of the animation system */
+void
+murrine_animation_cleanup ()
+{
+	disconnect_all_signals ();
+	
+	if (animated_widgets != NULL)
+	{
+		g_hash_table_destroy (animated_widgets);
+		animated_widgets = NULL;
+	}
+	
+	stop_timer ();
+}
+
+#endif /* HAVE_ANIMATION */

Added: trunk/src/animation.h
==============================================================================
--- (empty file)
+++ trunk/src/animation.h	Mon Feb 11 23:01:49 2008
@@ -0,0 +1,35 @@
+/* Murrine theme engine
+ * Copyright (C) 2007 Andrea Cimitan
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include "config.h"
+
+#ifdef HAVE_ANIMATION
+#include <gtk/gtk.h>
+
+#define MRN_IS_PROGRESS_BAR(widget) GTK_IS_PROGRESS_BAR(widget) && widget->allocation.x != -1 && widget->allocation.y != -1
+#define ANIMATION_DELAY 100
+#define CHECK_ANIMATION_TIME 0.5
+
+G_GNUC_INTERNAL void murrine_animation_progressbar_add (GtkWidget *progressbar);
+G_GNUC_INTERNAL void murrine_animation_connect_checkbox (GtkWidget *widget);
+G_GNUC_INTERNAL gboolean murrine_animation_is_animated (GtkWidget *widget);
+G_GNUC_INTERNAL gdouble murrine_animation_elapsed (gpointer data);
+G_GNUC_INTERNAL void murrine_animation_cleanup ();
+#endif /* HAVE_ANIMATION */

Added: trunk/src/cairo-support.c
==============================================================================
--- (empty file)
+++ trunk/src/cairo-support.c	Mon Feb 11 23:01:49 2008
@@ -0,0 +1,670 @@
+/* Murrine theme engine
+ * Copyright (C) 2007 Andrea Cimitan
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include "cairo-support.h"
+#include "support.h"
+#include <math.h>
+
+#include "murrine_types.h"
+
+G_GNUC_INTERNAL void
+murrine_rgb_to_hls (gdouble *r,
+                    gdouble *g,
+                    gdouble *b)
+{
+	gdouble min;
+	gdouble max;
+	gdouble red;
+	gdouble green;
+	gdouble blue;
+	gdouble h, l, s;
+	gdouble delta;
+
+	red = *r;
+	green = *g;
+	blue = *b;
+
+	if (red > green)
+	{
+		if (red > blue)
+			max = red;
+		else
+			max = blue;
+
+		if (green < blue)
+			min = green;
+		else
+			min = blue;
+	}
+	else
+	{
+		if (green > blue)
+			max = green;
+		else
+			max = blue;
+
+		if (red < blue)
+			min = red;
+		else
+			min = blue;
+	}
+
+	l = (max + min) / 2;
+	if (fabs(max - min) < 0.0001)
+	{
+		h = 0;
+		s = 0;
+	}
+	else
+	{
+		if (l <= 0.5)
+			s = (max - min) / (max + min);
+		else
+			s = (max - min) / (2 - max - min);
+
+		delta = max -min;
+		if (red == max)
+			h = (green - blue) / delta;
+		else if (green == max)
+			h = 2 + (blue - red) / delta;
+		else if (blue == max)
+			h = 4 + (red - green) / delta;
+
+		h *= 60;
+		if (h < 0.0)
+			h += 360;
+	}
+
+	*r = h;
+	*g = l;
+	*b = s;
+}
+
+G_GNUC_INTERNAL void
+murrine_hls_to_rgb (gdouble *h,
+                    gdouble *l,
+                    gdouble *s)
+{
+	gdouble hue;
+	gdouble lightness;
+	gdouble saturation;
+	gdouble m1, m2;
+	gdouble r, g, b;
+
+	lightness = *l;
+	saturation = *s;
+
+	if (lightness <= 0.5)
+		m2 = lightness * (1 + saturation);
+	else
+		m2 = lightness + saturation - lightness * saturation;
+
+	m1 = 2 * lightness - m2;
+
+	if (saturation == 0)
+	{
+		*h = lightness;
+		*l = lightness;
+		*s = lightness;
+	}
+	else
+	{
+		hue = *h + 120;
+		while (hue > 360)
+			hue -= 360;
+		while (hue < 0)
+			hue += 360;
+
+		if (hue < 60)
+			r = m1 + (m2 - m1) * hue / 60;
+		else if (hue < 180)
+			r = m2;
+		else if (hue < 240)
+			r = m1 + (m2 - m1) * (240 - hue) / 60;
+		else
+			r = m1;
+
+		hue = *h;
+		while (hue > 360)
+			hue -= 360;
+		while (hue < 0)
+			hue += 360;
+
+		if (hue < 60)
+			g = m1 + (m2 - m1) * hue / 60;
+		else if (hue < 180)
+			g = m2;
+		else if (hue < 240)
+			g = m1 + (m2 - m1) * (240 - hue) / 60;
+		else
+			g = m1;
+
+		hue = *h - 120;
+		while (hue > 360)
+			hue -= 360;
+		while (hue < 0)
+			hue += 360;
+
+		if (hue < 60)
+			b = m1 + (m2 - m1) * hue / 60;
+		else if (hue < 180)
+			b = m2;
+		else if (hue < 240)
+			b = m1 + (m2 - m1) * (240 - hue) / 60;
+		else
+			b = m1;
+
+		*h = r;
+		*l = g;
+		*s = b;
+	}
+}
+
+void
+murrine_shade (const MurrineRGB * a, MurrineRGB * b, float k)
+{
+	double red;
+	double green;
+	double blue;
+
+	red   = a->r;
+	green = a->g;
+	blue  = a->b;
+
+	if (k == 1.0)
+	{
+		b->r = red;
+		b->g = green;
+		b->b = blue;
+		return;
+	}
+
+	murrine_rgb_to_hls (&red, &green, &blue);
+
+	green *= k;
+	if (green > 1.0)
+		green = 1.0;
+	else if (green < 0.0)
+		green = 0.0;
+
+	blue *= k;
+	if (blue > 1.0)
+		blue = 1.0;
+	else if (blue < 0.0)
+		blue = 0.0;
+
+	murrine_hls_to_rgb (&red, &green, &blue);
+
+	b->r = red;
+	b->g = green;
+	b->b = blue;
+}
+
+void
+murrine_mix_color (const MurrineRGB *color1, const MurrineRGB *color2,
+                   gdouble mix_factor, MurrineRGB *composite)
+{
+	g_return_if_fail (color1 && color2 && composite);
+
+	composite->r = color1->r * (1-mix_factor) + color2->r * mix_factor;
+	composite->g = color1->g * (1-mix_factor) + color2->g * mix_factor;
+	composite->b = color1->b * (1-mix_factor) + color2->b * mix_factor;
+}
+
+void
+murrine_gdk_color_to_rgb (GdkColor *c, double *r, double *g, double *b)
+{
+	*r = (double)c->red   / (double)65535;
+	*g = (double)c->green / (double)65535;
+	*b = (double)c->blue  / (double)65535;
+}
+
+void
+murrine_get_parent_bg (const GtkWidget *widget, MurrineRGB *color)
+{
+	GtkStateType state_type;
+	const GtkWidget *parent;
+	GdkColor *gcolor;
+
+	if (widget == NULL)
+		return;
+
+	parent = widget->parent;
+
+	while (parent && GTK_WIDGET_NO_WINDOW (parent) && !((GTK_IS_NOTEBOOK (parent)) || (GTK_IS_TOOLBAR (parent))))
+		parent = parent->parent;
+
+	if (parent == NULL)
+		return;
+
+	state_type = GTK_WIDGET_STATE (parent);
+
+	gcolor = &parent->style->bg[state_type];
+
+	murrine_gdk_color_to_rgb (gcolor, &color->r, &color->g, &color->b);
+}
+
+void
+murrine_set_color_rgb (cairo_t *cr, const MurrineRGB *color)
+{
+	g_return_if_fail (cr && color);
+
+	cairo_set_source_rgb (cr, color->r, color->g, color->b);
+}
+
+void
+murrine_set_color_rgba (cairo_t *cr, const MurrineRGB *color, double alpha)
+{
+	g_return_if_fail (cr && color);
+
+	cairo_set_source_rgba (cr, color->r, color->g, color->b, alpha);
+}
+
+void
+murrine_rounded_corner (cairo_t *cr,
+                        double   x,
+                        double   y,
+                        int radius, uint8 corner)
+{
+	if (radius < 1)
+	{
+		cairo_line_to (cr, x, y);
+	}
+	else
+	{
+		switch (corner)
+		{
+			case MRN_CORNER_NONE:
+				cairo_line_to (cr, x, y);
+				break;
+			case MRN_CORNER_TOPLEFT:
+				cairo_arc (cr, x + radius, y + radius, radius, G_PI, G_PI * 3/2);
+				break;
+			case MRN_CORNER_TOPRIGHT:
+				cairo_arc (cr, x - radius, y + radius, radius, G_PI * 3/2, G_PI * 2);
+				break;
+			case MRN_CORNER_BOTTOMRIGHT:
+				cairo_arc (cr, x - radius, y - radius, radius, 0, G_PI * 1/2);
+				break;
+			case MRN_CORNER_BOTTOMLEFT:
+				cairo_arc (cr, x + radius, y - radius, radius, G_PI * 1/2, G_PI);
+				break;
+
+			default:
+				/* A bitfield and not a sane value ... */
+				g_assert_not_reached ();
+				cairo_line_to (cr, x, y);
+				return;
+		}
+	}
+}
+
+void
+murrine_rounded_rectangle_fast (cairo_t *cr,
+                                double x, double y, double w, double h,
+                                uint8 corners)
+{
+	const float RADIUS_CORNERS = 0.35;
+
+	if (corners & MRN_CORNER_TOPLEFT)
+		cairo_move_to (cr, x+RADIUS_CORNERS, y);
+	else
+		cairo_move_to (cr, x, y);
+
+	if (corners & MRN_CORNER_TOPRIGHT)
+	{
+		cairo_line_to (cr, x+w-RADIUS_CORNERS, y);
+		cairo_move_to (cr, x+w, y+RADIUS_CORNERS);
+	}
+	else
+		cairo_line_to (cr, x+w, y);
+
+	if (corners & MRN_CORNER_BOTTOMRIGHT)
+	{
+		cairo_line_to (cr, x+w, y+h-RADIUS_CORNERS);
+		cairo_move_to (cr, x+w-RADIUS_CORNERS, y+h);
+	}
+	else
+		cairo_line_to (cr, x+w, y+h);
+
+	if (corners & MRN_CORNER_BOTTOMLEFT)
+	{
+		cairo_line_to (cr, x+RADIUS_CORNERS, y+h);
+		cairo_move_to (cr, x, y+h-RADIUS_CORNERS);
+	}
+	else
+		cairo_line_to (cr, x, y+h);
+
+	if (corners & MRN_CORNER_TOPLEFT)
+		cairo_line_to (cr, x, y+RADIUS_CORNERS);
+	else
+	{
+		if (corners == MRN_CORNER_NONE)
+			cairo_close_path (cr);
+		else
+			cairo_line_to (cr, x, y);
+	}
+}
+
+void
+clearlooks_rounded_rectangle (cairo_t *cr,
+                              double x, double y, double w, double h,
+                              int radius, uint8 corners)
+{
+	if (radius < 1)
+	{
+		cairo_rectangle (cr, x, y, w, h);
+		return;
+	}
+
+	if (corners & MRN_CORNER_TOPLEFT)
+		cairo_move_to (cr, x+radius, y);
+	else
+		cairo_move_to (cr, x, y);
+
+	if (corners & MRN_CORNER_TOPRIGHT)
+		cairo_arc (cr, x+w-radius, y+radius, radius, M_PI * 1.5, M_PI * 2);
+	else
+		cairo_line_to (cr, x+w, y);
+
+	if (corners & MRN_CORNER_BOTTOMRIGHT)
+		cairo_arc (cr, x+w-radius, y+h-radius, radius, 0, M_PI * 0.5);
+	else
+		cairo_line_to (cr, x+w, y+h);
+
+	if (corners & MRN_CORNER_BOTTOMLEFT)
+		cairo_arc (cr, x+radius,   y+h-radius, radius, M_PI * 0.5, M_PI);
+	else
+		cairo_line_to (cr, x, y+h);
+
+	if (corners & MRN_CORNER_TOPLEFT)
+		cairo_arc (cr, x+radius,   y+radius,   radius, M_PI, M_PI * 1.5);
+	else
+		cairo_line_to (cr, x, y);
+}
+
+void
+murrine_rounded_rectangle (cairo_t *cr,
+                           double x, double y, double w, double h,
+                           int radius, uint8 corners)
+{
+	radius < 2 ? radius < 1 ? cairo_rectangle (cr, x, y, w, h) :
+	                          murrine_rounded_rectangle_fast (cr, x, y, w, h, corners) :
+	             clearlooks_rounded_rectangle (cr, x, y, w, h, radius, corners);
+}
+
+void
+murrine_draw_flat_highlight (cairo_t *cr,
+                             int x, int y, int width, int height)
+{
+	cairo_rectangle (cr, x, y, width, height/2);
+}
+
+void
+murrine_draw_curved_highlight (cairo_t *cr,
+                               double curve_pos, int width, int height)
+{
+	cairo_move_to (cr, curve_pos, height-curve_pos);
+	cairo_curve_to (cr, curve_pos, height/2+height/5, height/5, height/2, height/2, height/2);
+	cairo_line_to (cr, width-height/2, height/2);
+	cairo_curve_to (cr, width-curve_pos-height/5, height/2, width-curve_pos-0.5, height/2-height/5, width-curve_pos, curve_pos);
+	cairo_line_to (cr, curve_pos, curve_pos);
+	cairo_line_to (cr, curve_pos, height-curve_pos);
+	cairo_close_path (cr);
+}
+
+void
+murrine_draw_curved_highlight_top (cairo_t *cr,
+                                   double curve_pos, int width, int height)
+{
+	cairo_move_to (cr, curve_pos, curve_pos);
+	cairo_curve_to (cr, curve_pos, height/2-height/5, height/5, height/2, height/2, height/2);
+	cairo_line_to (cr, width-height/2, height/2);
+	cairo_curve_to (cr, width-curve_pos-height/5, height/2, width-curve_pos-0.5, height/2-height/5, width-curve_pos, curve_pos);
+	cairo_close_path (cr);
+}
+
+void
+murrine_draw_curved_highlight_bottom (cairo_t *cr,
+                                      double curve_pos, int width, int height)
+{
+	cairo_move_to (cr, curve_pos, height-curve_pos);
+	cairo_curve_to (cr, curve_pos, height/2+height/5, height/5, height/2, height/2, height/2);
+	cairo_line_to (cr, width-height/2, height/2);
+	cairo_curve_to (cr, width-curve_pos-height/5, height/2, width-curve_pos-0.5, height/2+height/5, width-curve_pos, height-curve_pos);
+	cairo_close_path (cr);
+}
+
+void
+murrine_draw_innerborder (cairo_t *cr,
+                          const MurrineRGB *highlight_color,
+                          const MurrineRGB *fill,
+                          MurrineGradients mrn_gradient,
+                          double x, double y, int width, int height,
+                          boolean gradients, boolean horizontal,
+                          int glazestyle, int radius, uint8 corners)
+{
+	cairo_pattern_t *pattern;
+	MurrineRGB shade1, shade2, shade3, shade4;
+	MurrineRGB fill_shade;
+	double alpha_value = 1.0;
+	if (mrn_gradient.use_rgba)
+	{
+		alpha_value = mrn_gradient.rgba_opacity;
+	}
+
+	if (gradients)
+	{
+		if (mrn_gradient.has_gradient_stop)
+		{
+			murrine_shade (highlight_color, &shade1, mrn_gradient.gradient_stop_1);
+			murrine_shade (highlight_color, &shade2, mrn_gradient.gradient_stop_2);
+			murrine_shade (highlight_color, &shade3, mrn_gradient.gradient_stop_3);
+			murrine_shade (highlight_color, &shade4, mrn_gradient.gradient_stop_4);
+			murrine_shade (fill, &fill_shade, mrn_gradient.gradient_stop_4);
+		}
+		else
+		{
+			murrine_shade (highlight_color, &shade1, 1.1);
+			murrine_shade (highlight_color, &shade2, 1.0);
+			murrine_shade (highlight_color, &shade3, 1.0);
+			murrine_shade (highlight_color, &shade4, 1.1);
+			murrine_shade (fill, &fill_shade, 1.1);
+		}
+	}
+	else
+	{
+		murrine_shade (highlight_color, &shade1, 1.0);
+		murrine_shade (highlight_color, &shade2, 1.0);
+		murrine_shade (highlight_color, &shade3, 1.0);
+		murrine_shade (highlight_color, &shade4, 1.0);
+		murrine_shade (fill, &fill_shade, 1.0);
+	}
+
+	double fill_pos = 1.0-(1.0/(!horizontal ? (double)(width) : (double)(height)));
+	if (corners == MRN_CORNER_ALL && radius > 2)
+		fill_pos = 1.0-((((double)radius-1.0)/2.0)/(!horizontal ? (double)(width) : (double)(height)));
+
+	radius < 2 ? cairo_rectangle (cr, x, y, width, height) :
+	             clearlooks_rounded_rectangle (cr, x, y, width, height, radius-1, corners);
+
+	pattern = cairo_pattern_create_linear (x, y, !horizontal ? width+x : x, !horizontal ? y : height+y);
+	cairo_pattern_add_color_stop_rgba (pattern,  0.0,      shade1.r, shade1.g, shade1.b, 0.5*alpha_value);
+	cairo_pattern_add_color_stop_rgba (pattern,  0.5,      shade2.r, shade2.g, shade2.b, 0.5*alpha_value);
+	cairo_pattern_add_color_stop_rgba (pattern,  0.5,      shade3.r, shade3.g, shade3.b, 0.5*alpha_value);
+	cairo_pattern_add_color_stop_rgba (pattern,  fill_pos, shade4.r, shade4.g, shade4.b, 0.5*alpha_value);
+	cairo_pattern_add_color_stop_rgba (pattern, fill_pos, fill_shade.r, fill_shade.g, fill_shade.b, 0.0);
+	cairo_pattern_add_color_stop_rgba (pattern, 1.0,      fill_shade.r, fill_shade.g, fill_shade.b, 0.0);
+	cairo_set_source (cr, pattern);
+	cairo_pattern_destroy (pattern);
+
+	cairo_stroke (cr);
+
+	if (glazestyle == 2)
+	{
+		murrine_set_gradient (cr, fill, mrn_gradient, x, y, 0, height, mrn_gradient.gradients, FALSE);
+		cairo_move_to (cr, width+x, y+0.5);
+		cairo_line_to (cr, width+x, height+y);
+		cairo_line_to (cr, x-0.5, height+y);
+		cairo_stroke (cr);
+	}
+}
+
+void
+murrine_set_gradient (cairo_t *cr,
+                      const MurrineRGB *color,
+                      MurrineGradients mrn_gradient,
+                      double x, double y, int width, int height,
+                      boolean gradients, boolean alpha)
+{
+	double alpha_value = 1.0;
+	if (mrn_gradient.use_rgba)
+	{
+		alpha_value = mrn_gradient.rgba_opacity;
+	}
+	else if (alpha)
+	{
+		alpha_value *= 0.8;
+	}
+
+	if (gradients)
+	{
+		cairo_pattern_t *pattern;
+		MurrineRGB shade1, shade2, shade3, shade4;
+
+		if (mrn_gradient.has_gradient_stop)
+		{
+			murrine_shade (color, &shade1, mrn_gradient.gradient_stop_1);
+			murrine_shade (color, &shade2, mrn_gradient.gradient_stop_2);
+			murrine_shade (color, &shade3, mrn_gradient.gradient_stop_3);
+			murrine_shade (color, &shade4, mrn_gradient.gradient_stop_4);
+		}
+		else
+		{
+			murrine_shade (color, &shade1, 1.1);
+			murrine_shade (color, &shade2, 1.0);
+			murrine_shade (color, &shade3, 1.0);
+			murrine_shade (color, &shade4, 1.1);
+		}
+
+		pattern = cairo_pattern_create_linear (x, y, width+x, height+y);
+		if (mrn_gradient.use_rgba)
+		{
+			cairo_pattern_add_color_stop_rgba (pattern, 0.0, shade1.r, shade1.g, shade1.b, alpha_value);
+			cairo_pattern_add_color_stop_rgba (pattern, 0.5, shade2.r, shade2.g, shade2.b, alpha_value);
+			cairo_pattern_add_color_stop_rgba (pattern, 0.5, shade3.r, shade3.g, shade3.b, alpha_value);
+			cairo_pattern_add_color_stop_rgba (pattern, 1.0, shade4.r, shade4.g, shade4.b, alpha_value);
+		}
+		else
+		{
+			if (!alpha)
+			{
+				cairo_pattern_add_color_stop_rgb (pattern, 0.0, shade1.r, shade1.g, shade1.b);
+				cairo_pattern_add_color_stop_rgb (pattern, 0.5, shade2.r, shade2.g, shade2.b);
+				cairo_pattern_add_color_stop_rgb (pattern, 0.5, shade3.r, shade3.g, shade3.b);
+				cairo_pattern_add_color_stop_rgb (pattern, 1.0, shade4.r, shade4.g, shade4.b);
+			}
+			else
+			{
+				cairo_pattern_add_color_stop_rgba (pattern, 0.0, shade1.r, shade1.g, shade1.b, alpha_value);
+				cairo_pattern_add_color_stop_rgba (pattern, 0.5, shade2.r, shade2.g, shade2.b, alpha_value);
+				cairo_pattern_add_color_stop_rgba (pattern, 0.5, shade3.r, shade3.g, shade3.b, alpha_value);
+				cairo_pattern_add_color_stop_rgba (pattern, 1.0, shade4.r, shade4.g, shade4.b, alpha_value);
+			}
+		}
+		cairo_set_source (cr, pattern);
+		cairo_pattern_destroy (pattern);
+	}
+	else
+	{
+		if (alpha_value < 1.0)
+			murrine_set_color_rgba (cr, color, alpha_value);
+		else
+			murrine_set_color_rgb (cr, color);
+	}
+}
+
+void
+rotate_mirror_translate (cairo_t *cr,
+                         double radius, double x, double y,
+                         boolean mirror_horizontally, boolean mirror_vertically)
+{
+	cairo_matrix_t matrix_rotate;
+	cairo_matrix_t matrix_mirror;
+	cairo_matrix_t matrix_result;
+
+	double r_cos = cos(radius);
+	double r_sin = sin(radius);
+
+	cairo_matrix_init (&matrix_rotate, r_cos, r_sin, r_sin, r_cos, x, y);
+
+	cairo_matrix_init (&matrix_mirror,
+	                   mirror_horizontally ? -1 : 1, 0, 0,
+	                   mirror_vertically ? -1 : 1, 0, 0);
+
+	cairo_matrix_multiply (&matrix_result, &matrix_mirror, &matrix_rotate);
+
+	cairo_set_matrix (cr, &matrix_result);
+}
+
+void
+murrine_exchange_axis (cairo_t  *cr,
+                       gint     *x,
+                       gint     *y,
+                       gint     *width,
+                       gint     *height)
+{
+	gint tmp;
+	cairo_matrix_t matrix;
+
+	cairo_translate (cr, *x, *y);
+	cairo_matrix_init (&matrix, 0, 1, 1, 0, 0, 0);
+
+	cairo_transform (cr, &matrix);
+
+	/* swap width/height */
+	tmp = *width;
+	*x = 0;
+	*y = 0;
+	*width = *height;
+	*height = tmp;
+}
+
+double
+get_decreased_ratio (double old, double factor)
+{
+	if (old > 1.0)
+		return ((old-1.0)/factor + 1.0);
+	else if (old < 1.0)
+		return (1.0 - (1.0-old)/factor);
+
+	return old;
+}
+
+double
+get_increased_ratio (double old, double factor)
+{
+	if (old > 1.0)
+		return ((old-1.0)*factor + 1.0);
+	else if (old < 1.0)
+		return (1.0 - (1.0-old)*factor);
+
+	return old;
+}

Added: trunk/src/cairo-support.h
==============================================================================
--- (empty file)
+++ trunk/src/cairo-support.h	Mon Feb 11 23:01:49 2008
@@ -0,0 +1,102 @@
+/* Murrine theme engine
+ * Copyright (C) 2007 Andrea Cimitan
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include <gtk/gtk.h>
+#include <math.h>
+
+#include "murrine_types.h"
+
+G_GNUC_INTERNAL void murrine_shade (const MurrineRGB *a, MurrineRGB *b,
+                                    float k);
+
+G_GNUC_INTERNAL void murrine_mix_color (const MurrineRGB *color1, const MurrineRGB *color2,
+                                        gdouble mix_factor, MurrineRGB *composite);
+
+G_GNUC_INTERNAL void murrine_gdk_color_to_rgb (GdkColor *c,
+                                               double *r, double *g, double *b);
+
+G_GNUC_INTERNAL void murrine_get_parent_bg (const GtkWidget *widget,
+                                            MurrineRGB *color);
+
+G_GNUC_INTERNAL void murrine_set_color_rgb (cairo_t *cr,
+                                            const MurrineRGB *color);
+
+G_GNUC_INTERNAL void murrine_set_color_rgba (cairo_t *cr,
+                                             const MurrineRGB *color,
+                                             double alpha);
+
+G_GNUC_INTERNAL void rotate_mirror_translate (cairo_t *cr,
+                                              double radius, double x, double y,
+                                              boolean mirror_horizontally, boolean mirror_vertically);
+
+G_GNUC_INTERNAL double get_decreased_ratio (double old, double factor);
+
+G_GNUC_INTERNAL double get_increased_ratio (double old, double factor);
+
+G_GNUC_INTERNAL void murrine_exchange_axis (cairo_t  *cr,
+                                            gint     *x,
+                                            gint     *y,
+                                            gint     *width,
+                                            gint     *height);
+
+G_GNUC_INTERNAL void murrine_rounded_corner (cairo_t *cr,
+                                             double x, double y,
+                                             int radius, uint8 corner);
+
+G_GNUC_INTERNAL void clearlooks_rounded_rectangle (cairo_t *cr,
+                                                   double x, double y, double w, double h,
+                                                   int radius, uint8 corners);
+
+G_GNUC_INTERNAL void murrine_rounded_rectangle (cairo_t *cr,
+                                                double x, double y, double w, double h,
+                                                int radius, uint8 corners);
+
+G_GNUC_INTERNAL void murrine_rounded_rectangle_fast (cairo_t *cr,
+                                                     double x, double y, double w, double h,
+                                                     uint8 corners);
+
+G_GNUC_INTERNAL void murrine_draw_innerborder (cairo_t *cr,
+                                               const MurrineRGB *highlight_color, const MurrineRGB *fill,
+                                               MurrineGradients mrn_gradient,
+                                               double x, double y, int width, int height,
+                                               boolean gradients, boolean horizontal,
+                                               int glazestyle, int radius, uint8 corners);
+
+G_GNUC_INTERNAL void murrine_set_gradient (cairo_t *cr,
+                                           const MurrineRGB *color,
+                                           MurrineGradients mrn_gradient,
+                                           double x, double y, int width, int height,
+                                           boolean gradients, boolean alpha);
+
+G_GNUC_INTERNAL void murrine_draw_flat_highlight (cairo_t *cr,
+                                                int x, int y, int width, int height);
+
+G_GNUC_INTERNAL void murrine_draw_curved_highlight (cairo_t *cr,
+                                                  double curve_pos,
+                                                  int width, int height);
+
+G_GNUC_INTERNAL void murrine_draw_curved_highlight_top (cairo_t *cr,
+                                                      double curve_pos,
+                                                      int width, int height);
+
+G_GNUC_INTERNAL void murrine_draw_curved_highlight_bottom (cairo_t *cr,
+                                                         double curve_pos,
+                                                         int width, int height);
+

Added: trunk/src/config.h.in
==============================================================================
--- (empty file)
+++ trunk/src/config.h.in	Mon Feb 11 23:01:49 2008
@@ -0,0 +1,64 @@
+/* src/config.h.in.  Generated from configure.ac by autoheader.  */
+
+/* Defines whether to compile with animation support */
+#undef HAVE_ANIMATION
+
+/* Defines whether to compile with progressbar animation from right to left */
+#undef HAVE_ANIMATIONTOLEFT
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#undef HAVE_DLFCN_H
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#undef HAVE_INTTYPES_H
+
+/* Defines whether to compile with mac menubar patches */
+#undef HAVE_MACMENU
+
+/* Define to 1 if you have the <memory.h> header file. */
+#undef HAVE_MEMORY_H
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#undef HAVE_STDINT_H
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#undef HAVE_STDLIB_H
+
+/* Define to 1 if you have the <strings.h> header file. */
+#undef HAVE_STRINGS_H
+
+/* Define to 1 if you have the <string.h> header file. */
+#undef HAVE_STRING_H
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#undef HAVE_SYS_STAT_H
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#undef HAVE_SYS_TYPES_H
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#undef HAVE_UNISTD_H
+
+/* Name of package */
+#undef PACKAGE
+
+/* Define to the address where bug reports for this package should be sent. */
+#undef PACKAGE_BUGREPORT
+
+/* Define to the full name of this package. */
+#undef PACKAGE_NAME
+
+/* Define to the full name and version of this package. */
+#undef PACKAGE_STRING
+
+/* Define to the one symbol short name of this package. */
+#undef PACKAGE_TARNAME
+
+/* Define to the version of this package. */
+#undef PACKAGE_VERSION
+
+/* Define to 1 if you have the ANSI C header files. */
+#undef STDC_HEADERS
+
+/* Version number of package */
+#undef VERSION

Added: trunk/src/murrine_draw.c
==============================================================================
--- (empty file)
+++ trunk/src/murrine_draw.c	Mon Feb 11 23:01:49 2008
@@ -0,0 +1,2402 @@
+/* Murrine theme engine
+ * Copyright (C) 2007 Andrea Cimitan
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include "murrine_draw.h"
+#include "murrine_style.h"
+#include "murrine_types.h"
+
+#include "support.h"
+#include "cairo-support.h"
+
+#include <cairo.h>
+
+#define M_PI 3.14159265358979323846
+
+static void
+murrine_draw_inset (cairo_t          *cr,
+                    const MurrineRGB *bg_color,
+                    double x, double y, double w, double h,
+                    double radius, uint8 corners)
+{
+	MurrineRGB shadow;
+	MurrineRGB highlight;
+
+	/* not really sure of shading ratios... we will think */
+	murrine_shade (bg_color, &shadow, 0.6);
+	murrine_shade (bg_color, &highlight, 1.4);
+
+	/* highlight */
+	cairo_move_to (cr, x + w + (radius * -0.2928932188), y - (radius * -0.2928932188)); /* 0.2928932... 1-sqrt(2)/2 gives middle of curve */
+
+	if (corners & MRN_CORNER_TOPRIGHT)
+		cairo_arc (cr, x + w - radius, y + radius, radius, M_PI * 1.75, M_PI * 2);
+	else
+		cairo_line_to (cr, x + w, y);
+
+	if (corners & MRN_CORNER_BOTTOMRIGHT)
+		cairo_arc (cr, x + w - radius, y + h - radius, radius, 0, M_PI * 0.5);
+	else
+		cairo_line_to (cr, x + w, y + h);
+
+	if (corners & MRN_CORNER_BOTTOMLEFT)
+		cairo_arc (cr, x + radius, y + h - radius, radius, M_PI * 0.5, M_PI * 0.75);
+	else
+		cairo_line_to (cr, x, y + h);
+
+	murrine_set_color_rgba (cr, &highlight, 0.45);
+	cairo_stroke (cr);
+
+	/* shadow */
+	cairo_move_to (cr, x + (radius * 0.2928932188), y + h + (radius * -0.2928932188));
+
+	if (corners & MRN_CORNER_BOTTOMLEFT)
+		cairo_arc (cr, x + radius, y + h - radius, radius, M_PI * 0.75, M_PI);
+	else
+		cairo_line_to (cr, x, y + h);
+
+	if (corners & MRN_CORNER_TOPLEFT)
+		cairo_arc (cr, x + radius, y + radius, radius, M_PI, M_PI * 1.5);
+	else
+		cairo_line_to (cr, x, y);
+
+	if (corners & MRN_CORNER_TOPRIGHT)
+	    cairo_arc (cr, x + w - radius, y + radius, radius, M_PI * 1.5, M_PI * 1.75);
+	else
+		cairo_line_to (cr, x + w, y);
+
+	murrine_set_color_rgba (cr, &shadow, 0.15);
+	cairo_stroke (cr);
+}
+
+static void
+murrine_draw_highlight_and_shade (cairo_t *cr,
+                                  const MurrineColors *colors,
+                                  const ShadowParameters *widget,
+                                  int width, int height, int radius)
+{
+	MurrineRGB highlight;
+	MurrineRGB shadow;
+	uint8 corners = widget->corners;
+	double x = 1.0;
+	double y = 1.0;
+
+	murrine_shade (&colors->bg[0], &highlight, 1.04);
+	murrine_shade (&colors->bg[0], &shadow, 0.96);
+
+	width  -= 3;
+	height -= 3;
+
+	cairo_save (cr);
+
+	/* Top/Left highlight */
+	if (corners & MRN_CORNER_BOTTOMLEFT)
+		cairo_move_to (cr, x, y+height-radius);
+	else
+		cairo_move_to (cr, x, y+height);
+
+	murrine_rounded_corner (cr, x, y, radius, corners & MRN_CORNER_TOPLEFT);
+
+	if (corners & MRN_CORNER_TOPRIGHT)
+		cairo_line_to (cr, x+width-radius, y);
+	else
+		cairo_line_to (cr, x+width, y);
+
+	if (widget->shadow & MRN_SHADOW_OUT)
+		murrine_set_color_rgb (cr, &highlight);
+	else
+		murrine_set_color_rgb (cr, &shadow);
+
+	cairo_stroke (cr);
+
+	/* Bottom/Right highlight -- this includes the corners */
+	cairo_move_to (cr, x+width-radius, y); /* topright and by radius to the left */
+	murrine_rounded_corner (cr, x+width, y, radius, corners & MRN_CORNER_TOPRIGHT);
+	murrine_rounded_corner (cr, x+width, y+height, radius, corners & MRN_CORNER_BOTTOMRIGHT);
+	murrine_rounded_corner (cr, x, y+height, radius, corners & MRN_CORNER_BOTTOMLEFT);
+
+	if (widget->shadow & MRN_SHADOW_OUT)
+		murrine_set_color_rgb (cr, &shadow);
+	else
+		murrine_set_color_rgb (cr, &highlight);
+
+	cairo_stroke (cr);
+
+	cairo_restore (cr);
+}
+
+static void
+murrine_draw_button (cairo_t *cr,
+                     const MurrineColors    *colors,
+                     const WidgetParameters *widget,
+                     int x, int y, int width, int height,
+                     boolean horizontal)
+{
+	double xoffset = 0, yoffset = 0;
+	MurrineRGB fill = colors->bg[widget->state_type];
+	MurrineRGB border_disabled = colors->shade[5];
+	MurrineRGB border_normal;
+	MurrineRGB highlight;
+
+	double custom_highlight_ratio = widget->highlight_ratio;
+	MurrineGradients mrn_gradient_custom = widget->mrn_gradient;
+
+	if (widget->disabled)
+	{
+		mrn_gradient_custom.gradient_stop_1 = get_decreased_ratio (widget->mrn_gradient.gradient_stop_1, 3.0);
+		mrn_gradient_custom.gradient_stop_2 = get_decreased_ratio (widget->mrn_gradient.gradient_stop_2, 3.0);
+		mrn_gradient_custom.gradient_stop_3 = get_decreased_ratio (widget->mrn_gradient.gradient_stop_3, 3.0);
+		mrn_gradient_custom.gradient_stop_4 = get_decreased_ratio (widget->mrn_gradient.gradient_stop_4, 3.0);
+		custom_highlight_ratio = get_decreased_ratio (widget->highlight_ratio, 2.0);
+	}
+
+	if (widget->is_default)
+		murrine_mix_color (&fill, &colors->spot[1], 0.2, &fill);
+
+	if (!horizontal)
+		murrine_exchange_axis (cr, &x, &y, &width, &height);
+
+	murrine_shade (&colors->shade[6], &border_normal, 0.95);
+	murrine_shade (&fill, &highlight, custom_highlight_ratio);
+
+	cairo_translate (cr, x, y);
+	cairo_set_line_width (cr, 1.0);
+
+	if (widget->xthickness > 1)
+		xoffset = 1;
+	if (widget->ythickness > 1)
+		yoffset = 1;
+
+	/* Start drawing the inset/shadow */
+	if (!widget->active && !widget->disabled)
+	{
+		murrine_rounded_rectangle (cr, xoffset, yoffset, width-(xoffset*2), height-(yoffset*2), widget->roundness, widget->corners);
+		murrine_set_color_rgba (cr, widget->disabled ? &border_disabled : &border_normal, 0.18);
+		cairo_stroke (cr);
+	}
+	else
+		murrine_draw_inset (cr, &widget->parentbg, 0.5, 0.5, width-1, height-1, widget->roundness+1, widget->corners);
+
+	murrine_mix_color (widget->disabled ? &border_disabled : &border_normal , &fill, 0.4,
+	                   widget->disabled ? &border_disabled : &border_normal);
+
+	/* Default button */
+	if (widget->is_default)
+	{
+		murrine_rounded_rectangle (cr, xoffset, yoffset, width-(xoffset*2), height-(yoffset*2), widget->roundness, widget->corners);
+		murrine_set_color_rgba (cr, &colors->spot[1], 0.5);
+		cairo_stroke (cr);
+		murrine_shade (&border_normal, &border_normal, 0.8);
+	}
+
+	/* Draw the bg */
+	if (widget->roundness < 2)
+		cairo_rectangle (cr, xoffset + 1, yoffset + 1, width-(xoffset*2)-2, height-(yoffset*2)-2);
+	else
+		murrine_rounded_rectangle (cr, xoffset+0.5, yoffset+0.5, width-(xoffset*2)-1, height-(yoffset*2)-1, widget->roundness+1, widget->corners);
+	murrine_set_gradient (cr, &fill, mrn_gradient_custom, xoffset+1, yoffset+1, 0, height-(yoffset*2)-2, widget->mrn_gradient.gradients, FALSE);
+
+	cairo_save (cr);
+	if (widget->roundness > 1)
+		cairo_clip_preserve (cr);
+
+	int curve_pos = 1;
+	if (widget->glazestyle != 4)
+		curve_pos = 2;
+
+	/* Draw the glass effect */
+	if (widget->glazestyle > 0)
+	{
+		cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD);
+		widget->glazestyle == 2 ? cairo_fill_preserve (cr) : cairo_fill (cr);
+		if (widget->glazestyle < 3)
+			murrine_draw_curved_highlight (cr, curve_pos, width, height);
+		else
+			murrine_draw_curved_highlight_top (cr, curve_pos, width, height);
+	}
+	else
+	{
+		cairo_fill (cr);
+		murrine_draw_flat_highlight (cr, xoffset + 1, yoffset + 1, width-(xoffset*2)-2, height-(yoffset*2)-2);
+	}
+
+	murrine_set_gradient (cr, &highlight, mrn_gradient_custom, xoffset+1, yoffset+1, 0, height-(yoffset*2)-2, widget->mrn_gradient.gradients, TRUE);
+	cairo_fill (cr);
+
+	if (widget->glazestyle == 4)
+	{
+		murrine_draw_curved_highlight_bottom (cr, curve_pos, width, height);
+		MurrineRGB shadow;
+		murrine_shade (&fill, &shadow, 1.0/custom_highlight_ratio);
+		murrine_set_gradient (cr, &shadow, mrn_gradient_custom, xoffset+1, yoffset+1, 0, height-(yoffset*2)-2, widget->mrn_gradient.gradients, TRUE);
+		cairo_fill (cr);
+	}
+
+	/* Draw the white inner border */
+	if (widget->glazestyle != 4 && !widget->active)
+	{
+		murrine_shade (&fill, &highlight, widget->innerborder_ratio*custom_highlight_ratio);
+		if (horizontal)
+		{
+			murrine_draw_innerborder (cr, &highlight, &fill, mrn_gradient_custom,
+			                          xoffset + 1.5, yoffset + 1.5,
+			                          width-(xoffset*2)-3, height-(yoffset*2)-3,
+			                          widget->mrn_gradient.gradients, horizontal,
+			                          widget->glazestyle, widget->roundness, widget->corners);
+		}
+		else
+		{
+			murrine_exchange_axis (cr, &x, &y, &width, &height);
+			murrine_draw_innerborder (cr, &highlight, &fill, mrn_gradient_custom,
+			                          xoffset + 1.5, yoffset + 1.5,
+			                          width-(xoffset*2)-3, height-(yoffset*2)-3,
+			                          widget->mrn_gradient.gradients, horizontal,
+			                          widget->glazestyle, widget->roundness, widget->corners);
+			murrine_exchange_axis (cr, &x, &y, &width, &height);
+		}
+	}
+	cairo_restore (cr);
+
+	/* Draw pressed button shadow */
+	if (widget->active)
+	{
+		cairo_pattern_t *pattern;
+		MurrineRGB shadow;
+
+		murrine_shade (&fill, &shadow, 0.94);
+
+		cairo_save (cr);
+
+		if (widget->roundness < 2)
+			cairo_rectangle (cr, xoffset + 1, yoffset + 1, width-(xoffset*2)-2, height-(yoffset*2)-2);
+		else
+			clearlooks_rounded_rectangle (cr, xoffset+1, yoffset+1, width-(xoffset*2)-2, height-(yoffset*2)-2, widget->roundness-1,
+			                              widget->corners & (MRN_CORNER_TOPLEFT | MRN_CORNER_TOPRIGHT | MRN_CORNER_BOTTOMLEFT));
+
+		cairo_clip (cr);
+
+		cairo_rectangle (cr, xoffset+1, yoffset+1, width-(xoffset*2)-2, 3);
+		pattern = cairo_pattern_create_linear (xoffset+1, yoffset+1, xoffset+1, yoffset+4);
+		cairo_pattern_add_color_stop_rgba (pattern, 0.0, shadow.r, shadow.g, shadow.b, 0.58);
+		cairo_pattern_add_color_stop_rgba (pattern, 1.0, shadow.r, shadow.g, shadow.b, 0.0);
+		cairo_set_source (cr, pattern);
+		cairo_fill (cr);
+		cairo_pattern_destroy (pattern);
+
+		cairo_rectangle (cr, xoffset+1, yoffset+1, 3, height-(yoffset*2)-2);
+		pattern = cairo_pattern_create_linear (xoffset+1, yoffset+1, xoffset+4, yoffset+1);
+		cairo_pattern_add_color_stop_rgba (pattern, 0.0, shadow.r, shadow.g, shadow.b, 0.58);
+		cairo_pattern_add_color_stop_rgba (pattern, 1.0, shadow.r, shadow.g, shadow.b, 0.0);
+		cairo_set_source (cr, pattern);
+		cairo_fill (cr);
+		cairo_pattern_destroy (pattern);
+
+		cairo_restore (cr);
+	}
+
+	/* Draw the border */
+	murrine_set_color_rgb (cr, widget->disabled ? &border_disabled : &border_normal);
+	murrine_rounded_rectangle (cr, xoffset+0.5, yoffset+0.5, width-(xoffset*2)-1, height-(yoffset*2)-1, widget->roundness, widget->corners);
+	cairo_stroke (cr);
+}
+
+static void
+murrine_draw_entry (cairo_t *cr,
+                    const MurrineColors    *colors,
+                    const WidgetParameters *widget,
+                    int x, int y, int width, int height)
+{
+	const MurrineRGB *base = &colors->base[widget->state_type];
+	MurrineRGB *border;
+	int radius = CLAMP (widget->roundness, 0, 3);
+
+	if (widget->focus)
+		border = (MurrineRGB*)&colors->spot[2];
+	else
+		border = (MurrineRGB*)&colors->shade[widget->disabled ? 4 : 6];
+
+	cairo_translate (cr, x+0.5, y+0.5);
+	cairo_set_line_width (cr, 1.0);
+
+	/* Fill the background (shouldn't have to) */
+	cairo_rectangle (cr, -0.5, -0.5, width, height);
+	murrine_set_color_rgb (cr, &widget->parentbg);
+	cairo_fill (cr);
+
+	/* Fill the entry's base color (why isn't is large enough by default?) */
+	cairo_rectangle (cr, 1.5, 1.5, width-4, height-4);
+	murrine_set_color_rgb (cr, base);
+	cairo_fill (cr);
+
+	murrine_draw_inset (cr, &widget->parentbg, 0, 0, width-1, height-1, radius+1, widget->corners);
+
+	/* Draw the focused border */
+	if (widget->focus)
+	{
+		cairo_rectangle (cr, 2, 2, width-5, height-5);
+		murrine_set_color_rgb (cr, &colors->spot[1]);
+		cairo_stroke(cr);
+	}
+	else
+	{
+		MurrineRGB shadow;
+		murrine_shade (border, &shadow, 0.925);
+
+		cairo_move_to (cr, 2, height-3);
+		cairo_line_to (cr, 2, 2);
+		cairo_line_to (cr, width-3, 2);
+
+		murrine_set_color_rgba (cr, &shadow, widget->disabled ? 0.05 : 0.15);
+		cairo_stroke (cr);
+	}
+
+	/* Draw the border */
+	murrine_set_color_rgb (cr, border);
+	murrine_rounded_rectangle (cr, 1, 1, width-3, height-3, radius, widget->corners);
+	cairo_stroke (cr);
+}
+
+static void
+murrine_draw_spinbutton_down (cairo_t *cr,
+                              const MurrineColors    *colors,
+                              const WidgetParameters *widget,
+                              int x, int y, int width, int height)
+{
+	MurrineRGB shadow;
+	murrine_shade (&colors->bg[0], &shadow, 0.8);
+
+	cairo_pattern_t *pattern;
+
+	cairo_translate (cr, x+1, y+1);
+
+	cairo_rectangle (cr, 1, 1, width-4, height-4);
+
+	pattern = cairo_pattern_create_linear (0, 0, 0, height);
+	cairo_pattern_add_color_stop_rgb (pattern, 0.0, shadow.r, shadow.g, shadow.b);
+	cairo_pattern_add_color_stop_rgba (pattern, 1.0, shadow.r, shadow.g, shadow.b, 0.0);
+
+	cairo_set_source (cr, pattern);
+	cairo_fill (cr);
+
+	cairo_pattern_destroy (pattern);
+}
+
+static void
+murrine_scale_draw_gradient (cairo_t *cr,
+                             const MurrineRGB *c1,
+                             const MurrineRGB *c2,
+                             int x, int y, int width, int height,
+                             boolean alpha)
+{
+	if (alpha)
+		murrine_set_color_rgba (cr, c1, 0.4);
+	else
+		murrine_set_color_rgb (cr, c1);
+
+	cairo_rectangle (cr, x, y, width, height);
+	cairo_fill (cr);
+
+	cairo_rectangle (cr, x, y, width, height);
+	murrine_set_color_rgba (cr, c2, 0.8);
+	cairo_stroke (cr);
+}
+
+static void
+murrine_draw_scale_trough (cairo_t *cr,
+                           const MurrineColors    *colors,
+                           const WidgetParameters *widget,
+                           const SliderParameters *slider,
+                           int x, int y, int width, int height)
+{
+	int     fill_x, fill_y, fill_width, fill_height; /* Fill x,y,w,h */
+	int     trough_width, trough_height;
+	double  translate_x, translate_y;
+	int     fill_size = slider->fill_size;
+	int     TROUGH_SIZE = 6;
+
+	if (slider->horizontal)
+	{
+		if (fill_size > width-3)
+			fill_size = width-3;
+
+		fill_x        = slider->inverted ? width - fill_size - 3 : 0;
+		fill_y        = 0;
+		fill_width    = fill_size;
+		fill_height   = TROUGH_SIZE-2;
+
+		trough_width  = width-3;
+		trough_height = TROUGH_SIZE-2;
+
+		translate_x   = x + 0.5;
+		translate_y   = y + 0.5 + (height/2) - (TROUGH_SIZE/2);
+	}
+	else
+	{
+		if (fill_size > height-3)
+			fill_size = height-3;
+
+		fill_x        = 0;
+		fill_y        = slider->inverted ? height - fill_size - 3 : 0;
+		fill_width    = TROUGH_SIZE-2;
+		fill_height   = fill_size;
+
+		trough_width  = TROUGH_SIZE-2;
+		trough_height = height-3;
+
+		translate_x   = x + 0.5 + (width/2) - (TROUGH_SIZE/2);
+		translate_y   = y + 0.5;
+	}
+
+	cairo_set_line_width (cr, 1.0);
+	cairo_translate (cr, translate_x, translate_y);
+
+	murrine_draw_inset (cr, &widget->parentbg, 0, 0, trough_width+2, trough_height+2, 0, 0);
+
+	cairo_translate (cr, 1, 1);
+
+	murrine_scale_draw_gradient (cr, &colors->shade[1],
+	                             &colors->shade[4], /* border */
+	                             0, 0, trough_width, trough_height,
+	                             TRUE);
+
+	murrine_scale_draw_gradient (cr, &colors->spot[1],
+	                             &colors->spot[2], /* border */
+	                             fill_x, fill_y, fill_width, fill_height,
+	                             FALSE);
+}
+
+static void
+murrine_draw_slider_handle (cairo_t *cr,
+                            const MurrineColors    *colors,
+                            const WidgetParameters *widget,
+                            int x, int y, int width, int height,
+                            boolean horizontal)
+{
+	MurrineRGB handle;
+	murrine_shade (&colors->shade[6], &handle, 0.95);
+
+	murrine_mix_color (&handle, &colors->bg[widget->state_type], 0.4, &handle);
+
+	if (!horizontal)
+	{
+		rotate_mirror_translate (cr, M_PI/2, x, y, FALSE, FALSE);
+		int tmp = height; height = width; width = tmp;
+	}
+
+	int num_handles = 2;
+	if (width%2 != 0)
+		num_handles = 3;
+
+	int bar_x = width/2 - num_handles;
+	cairo_translate (cr, 0.5, 0.5);
+	int i;
+	for (i=0; i<num_handles; i++)
+	{
+		cairo_move_to (cr, bar_x, 3.5);
+		cairo_line_to (cr, bar_x, height-4.5);
+		murrine_set_color_rgb (cr, &handle);
+		cairo_stroke (cr);
+		bar_x += 3;
+	}
+}
+
+static void
+murrine_draw_progressbar_trough (cairo_t *cr,
+                                 const MurrineColors    *colors,
+                                 const WidgetParameters *widget,
+                                 int x, int y, int width, int height)
+{
+	const MurrineRGB *border = &colors->shade[3];
+
+	cairo_set_line_width (cr, 1.0);
+
+	/* Fill with bg color */
+	cairo_rectangle (cr, x, y, width, height);
+	murrine_set_color_rgb (cr, &colors->bg[widget->state_type]);
+	cairo_fill (cr);
+
+	/* Create trough box */
+	cairo_rectangle (cr, x+1, y+1, width-2, height-2);
+	murrine_set_color_rgba (cr, &colors->shade[1], 0.4);
+	cairo_fill (cr);
+
+	/* Draw border */
+	cairo_rectangle (cr, x+0.5, y+0.5, width-1, height-1);
+	murrine_set_color_rgba (cr, border, 0.8);
+	cairo_stroke (cr);
+}
+
+static void
+murrine_draw_progressbar_fill (cairo_t *cr,
+                               const MurrineColors         *colors,
+                               const WidgetParameters      *widget,
+                               const ProgressBarParameters *progressbar,
+                               int x, int y, int width, int height,
+                               gint offset)
+{
+	boolean    is_horizontal = progressbar->orientation < 2;
+	double     tile_pos = 0;
+	double     stroke_width;
+	int        x_step;
+	const      MurrineRGB *fill = &colors->spot[1];
+	const      MurrineRGB *border = &colors->spot[2];
+	MurrineRGB highlight;
+
+	murrine_shade (fill, &highlight, widget->highlight_ratio);
+
+	cairo_rectangle (cr, x, y, width, height);
+
+	if (is_horizontal)
+	{
+		if (progressbar->orientation == MRN_ORIENTATION_LEFT_TO_RIGHT)
+			rotate_mirror_translate (cr, 0, x, y, FALSE, FALSE);
+		else
+			rotate_mirror_translate (cr, 0, x+width, y, TRUE, FALSE);
+	}
+	else
+	{
+		int tmp = height; height  = width; width   = tmp;
+
+		x = x + 1;
+		y = y - 1;
+		width = width + 2;
+		height = height - 2;
+
+		if (progressbar->orientation == MRN_ORIENTATION_TOP_TO_BOTTOM)
+			rotate_mirror_translate (cr, M_PI/2, x, y, FALSE, FALSE);
+		else
+			rotate_mirror_translate (cr, M_PI/2, x, y+width, TRUE, FALSE);
+	}
+
+	cairo_save (cr);
+	cairo_clip (cr);
+
+	stroke_width = height*2;
+	x_step = (((float)stroke_width/10)*offset);
+	cairo_set_line_width (cr, 1.0);
+	cairo_save (cr);
+	cairo_rectangle (cr, 1.5, 0.5, width-2, height-1);
+
+	/* Draw fill */
+	murrine_set_gradient (cr, fill, widget->mrn_gradient, 1.5, 0.5, 0, height-1, widget->mrn_gradient.gradients, FALSE);
+
+	/* Draw the glass effect */
+	if (widget->glazestyle > 0)
+	{
+		widget->glazestyle == 2 ? cairo_fill_preserve (cr) : cairo_fill (cr);
+		if (widget->glazestyle < 3)
+			murrine_draw_curved_highlight (cr, 1, width, height);
+		else
+			murrine_draw_curved_highlight_top (cr, 1, width, height);
+	}
+	else
+	{
+		cairo_fill (cr);
+		murrine_draw_flat_highlight (cr, 1.5, 0.5, width-2, height);
+	}
+
+	murrine_set_gradient (cr, &highlight, widget->mrn_gradient, 1.5, 0.5, 0, height-1, widget->mrn_gradient.gradients, TRUE);
+	cairo_fill (cr);
+
+	if (widget->glazestyle == 4)
+	{
+		murrine_draw_curved_highlight_bottom (cr, 1, width, height+1);
+		MurrineRGB shadow;
+		murrine_shade (fill, &shadow, 1.0/widget->highlight_ratio);
+		murrine_set_gradient (cr, &shadow, widget->mrn_gradient, 1.5, 0.5, 0, height-1, widget->mrn_gradient.gradients, TRUE);
+		cairo_fill (cr);
+	}
+
+	murrine_shade (fill, &highlight, widget->highlight_ratio*widget->innerborder_ratio);
+	murrine_draw_innerborder (cr, &highlight, fill, widget->mrn_gradient,
+	                          2.5, 1.5,
+	                          width-5, height-3,
+	                          widget->mrn_gradient.gradients, TRUE,
+	                          widget->glazestyle, 0, MRN_CORNER_NONE);
+
+	/* Draw strokes */
+	while (tile_pos <= width+x_step-2)
+	{
+		cairo_move_to (cr, stroke_width/2-x_step, 0);
+		cairo_line_to (cr, stroke_width-x_step,   0);
+		cairo_line_to (cr, stroke_width/2-x_step, height);
+		cairo_line_to (cr, -x_step, height);
+
+		cairo_translate (cr, stroke_width, 0);
+		tile_pos += stroke_width;
+	}
+
+	murrine_set_color_rgba (cr, border, 0.15);
+	cairo_fill (cr);
+	cairo_restore (cr);
+
+	/* Draw the border */
+	murrine_set_color_rgba (cr, border, 0.8);
+	cairo_rectangle (cr, 1.5, 0.5, width-3, height-1);
+	cairo_stroke (cr);
+}
+
+static void
+murrine_draw_optionmenu (cairo_t *cr,
+                         const MurrineColors        *colors,
+                         const WidgetParameters     *widget,
+                         const OptionMenuParameters *optionmenu,
+                         int x, int y, int width, int height)
+{
+	int offset = widget->ythickness + 1;
+
+	boolean horizontal = TRUE;
+	if (((float)width/height<0.5) || (widget->glazestyle > 0 && width<height))
+		horizontal = FALSE;
+
+	widget->style_functions->draw_button (cr, colors, widget, x, y, width, height, horizontal);
+
+	/* Draw the separator */
+	MurrineRGB *dark = (MurrineRGB*)&colors->shade[6];
+
+	cairo_set_line_width   (cr, 1.0);
+	cairo_translate        (cr, optionmenu->linepos+0.5, 1);
+
+	cairo_move_to          (cr, 0.0, offset);
+	cairo_line_to          (cr, 0.0, height - offset - widget->ythickness + 1);
+	murrine_set_color_rgba (cr, dark, 0.4);
+	cairo_stroke           (cr);
+}
+
+static void
+murrine_draw_menubar (cairo_t *cr,
+                      const MurrineColors *colors,
+                      const WidgetParameters *widget,
+                      int x, int y, int width, int height,
+                      int menubarstyle)
+{
+	cairo_translate (cr, x, y);
+	cairo_rectangle (cr, 0, 0, width, height);
+	const MurrineRGB *fill = &colors->bg[0];
+
+	if (menubarstyle == 1) /* Glass menubar */
+	{
+		MurrineRGB highlight;
+		murrine_set_gradient (cr, fill, widget->mrn_gradient, 0, 0, 0, height, widget->mrn_gradient.gradients, FALSE);
+		murrine_shade (fill, &highlight, widget->highlight_ratio);
+		/* The glass effect */
+		if (widget->glazestyle > 0)
+		{
+			widget->glazestyle == 2 ? cairo_fill_preserve (cr) : cairo_fill (cr);
+			if (widget->glazestyle < 3)
+				murrine_draw_curved_highlight (cr, 0, width, height);
+			else
+				murrine_draw_curved_highlight_top (cr, 0, width, height);
+		}
+		else
+		{
+			cairo_fill (cr);
+			murrine_draw_flat_highlight (cr, 0, 0, width, height);
+		}
+
+		murrine_set_gradient (cr, &highlight, widget->mrn_gradient, 0, 0, 0, height, widget->mrn_gradient.gradients, TRUE);
+		cairo_fill (cr);
+
+		if (widget->glazestyle == 4)
+		{
+			murrine_draw_curved_highlight_bottom (cr, 0, width, height);
+			MurrineRGB shadow;
+			murrine_shade (fill, &shadow, 1.0/widget->highlight_ratio);
+			murrine_set_color_rgb (cr, &shadow);
+			cairo_fill (cr);
+		}
+
+		if (widget->glazestyle == 2)
+		{
+			murrine_draw_innerborder (cr, &highlight, fill, widget->mrn_gradient,
+			                          1.5, 1.5,
+			                          width-3, height-3,
+			                          widget->mrn_gradient.gradients, TRUE,
+			                          widget->glazestyle, widget->roundness, widget->corners);
+		}
+	}
+	else if (menubarstyle == 2) /* Gradient menubar */
+	{
+		cairo_pattern_t *pattern;
+		MurrineRGB lower;
+		murrine_shade (fill, &lower, 0.95);
+		pattern = cairo_pattern_create_linear (0, 0, 0, height);
+		if (!widget->mrn_gradient.use_rgba)
+		{
+			cairo_pattern_add_color_stop_rgb (pattern, 0.0, fill->r, fill->g, fill->b);
+			cairo_pattern_add_color_stop_rgb (pattern, 1.0, lower.r, lower.g, lower.b);
+		}
+		else
+		{
+			cairo_pattern_add_color_stop_rgba (pattern, 0.0, fill->r, fill->g, fill->b, 0.7);
+			cairo_pattern_add_color_stop_rgba (pattern, 1.0, lower.r, lower.g, lower.b, 0.7);
+		}
+		cairo_set_source (cr, pattern);
+		cairo_fill (cr);
+		cairo_pattern_destroy (pattern);
+	}
+	else if (menubarstyle == 3) /* Striped menubar */
+	{
+		cairo_pattern_t *pattern;
+		MurrineRGB low, top;
+		murrine_shade (fill, &top, 0.9);
+		murrine_shade (fill, &low, 1.1);
+		pattern = cairo_pattern_create_linear (0, 0, 0, height);
+		cairo_pattern_add_color_stop_rgb (pattern, 0.0, top.r, top.g, top.b);
+		cairo_pattern_add_color_stop_rgb (pattern, 1.0, low.r, low.g, low.b);
+		cairo_set_source (cr, pattern);
+		cairo_fill (cr);
+		cairo_pattern_destroy (pattern);
+		int counter = -height;
+		cairo_set_line_width  (cr, 1.0);
+		murrine_shade (&low, &low, 0.9);
+		murrine_set_color_rgb (cr, &low);
+		while (counter < width)
+		{
+			cairo_move_to (cr, counter, height);
+			cairo_line_to (cr, counter+height, 0);
+			cairo_stroke  (cr);
+			counter += 5;
+		}
+	}
+	else /* Flat menubar */
+	{
+		murrine_set_color_rgb (cr, fill);
+		cairo_fill (cr);
+	}
+
+	/* Draw bottom line */
+	if (menubarstyle == 1 && widget->glazestyle == 2)
+		cairo_rectangle (cr, 0.5, 0.5, width-1, height-1);
+#ifndef HAVE_MACMENU
+	else
+	{
+		cairo_set_line_width (cr, 1.0);
+		cairo_move_to        (cr, 0, height-0.5);
+		cairo_line_to        (cr, width, height-0.5);
+	}
+	murrine_set_color_rgb (cr, &colors->shade[3]);
+	cairo_stroke          (cr);
+#endif
+}
+
+static void
+murrine_get_frame_gap_clip (int x, int y, int width, int height,
+                            const FrameParameters *frame,
+                            MurrineRectangle      *bevel,
+                            MurrineRectangle      *border)
+{
+	if (frame->gap_side == MRN_GAP_TOP)
+	{
+		MURRINE_RECTANGLE_SET ((*bevel),  1.5 + frame->gap_x,  -0.5,
+		                       frame->gap_width - 3, 2.0);
+		MURRINE_RECTANGLE_SET ((*border), 0.5 + frame->gap_x,  -0.5,
+		                       frame->gap_width - 2, 2.0);
+	}
+	else if (frame->gap_side == MRN_GAP_BOTTOM)
+	{
+		MURRINE_RECTANGLE_SET ((*bevel),  1.5 + frame->gap_x,  height - 2.5,
+		                       frame->gap_width - 3, 2.0);
+		MURRINE_RECTANGLE_SET ((*border), 0.5 + frame->gap_x,  height - 1.5,
+		                       frame->gap_width - 2, 2.0);
+	}
+	else if (frame->gap_side == MRN_GAP_LEFT)
+	{
+		MURRINE_RECTANGLE_SET ((*bevel),  -0.5, 1.5 + frame->gap_x,
+		                       2.0, frame->gap_width - 3);
+		MURRINE_RECTANGLE_SET ((*border), -0.5, 0.5 + frame->gap_x,
+		                       1.0, frame->gap_width - 2);
+	}
+	else if (frame->gap_side == MRN_GAP_RIGHT)
+	{
+		MURRINE_RECTANGLE_SET ((*bevel),  width - 2.5, 1.5 + frame->gap_x,
+		                       2.0, frame->gap_width - 3);
+		MURRINE_RECTANGLE_SET ((*border), width - 1.5, 0.5 + frame->gap_x,
+		                       1.0, frame->gap_width - 2);
+	}
+}
+
+static void
+murrine_draw_frame (cairo_t *cr,
+                    const MurrineColors    *colors,
+                    const WidgetParameters *widget,
+                    const FrameParameters  *frame,
+                    int x, int y, int width, int height)
+{
+	MurrineRGB *border = frame->border;
+	MurrineRectangle bevel_clip;
+	MurrineRectangle frame_clip;
+
+	const MurrineRGB *dark = &colors->shade[3];
+
+	MurrineRGB highlight, shadow_color;
+	murrine_shade (&colors->bg[0], &highlight, 1.04);
+	murrine_shade (&colors->bg[0], &shadow_color, 0.96);
+
+	if (frame->shadow == MRN_SHADOW_NONE)
+		return;
+
+	if (frame->gap_x != -1)
+		murrine_get_frame_gap_clip (x, y, width, height,
+		                            frame, &bevel_clip, &frame_clip);
+
+	cairo_set_line_width (cr, 1.0);
+	cairo_translate      (cr, x+0.5, y+0.5);
+
+	/* save everything */
+	cairo_save (cr);
+
+	/* Set clip for the bevel */
+	if (frame->gap_x != -1)
+	{
+		/* Set clip for gap */
+		cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD);
+		cairo_rectangle     (cr, -0.5, -0.5, width, height);
+		cairo_rectangle     (cr, bevel_clip.x, bevel_clip.y, bevel_clip.width, bevel_clip.height);
+		cairo_clip          (cr);
+	}
+
+	/* Draw the bevel */
+	if (frame->shadow == MRN_SHADOW_ETCHED_IN || frame->shadow == MRN_SHADOW_ETCHED_OUT)
+	{
+		murrine_set_color_rgb (cr, &highlight);
+		if (frame->shadow == MRN_SHADOW_ETCHED_IN)
+			murrine_rounded_rectangle (cr, 1, 1, width-2, height-2, widget->roundness, widget->corners);
+		else
+			murrine_rounded_rectangle (cr, 0, 0, width-2, height-2, widget->roundness, widget->corners);
+		cairo_stroke (cr);
+	}
+	else if (frame->shadow != MRN_SHADOW_NONE && frame->shadow != MRN_SHADOW_FLAT)
+	{
+		ShadowParameters shadow;
+		shadow.corners = widget->corners;
+		shadow.shadow  = frame->shadow;
+		cairo_move_to (cr, 1, height-2);
+		cairo_line_to (cr, 1, 1);
+		cairo_line_to (cr, width-1.5, 1);
+		if (frame->shadow & MRN_SHADOW_OUT)
+			murrine_set_color_rgb (cr, &highlight);
+		else
+			murrine_set_color_rgb (cr, &shadow_color);
+		cairo_stroke (cr);
+		cairo_move_to (cr, width-2, 1.5);
+		cairo_line_to (cr, width-2, height-2);
+		cairo_line_to (cr, 0, height-2);
+		if (frame->shadow & MRN_SHADOW_OUT)
+			murrine_set_color_rgb (cr, &shadow_color);
+		else
+			murrine_set_color_rgb (cr, &highlight);
+		cairo_stroke (cr);
+	}
+
+	/* restore the previous clip region */
+	cairo_restore (cr);
+	cairo_save    (cr);
+	if (frame->gap_x != -1)
+	{
+		/* Set clip for gap */
+		cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD);
+		cairo_rectangle     (cr, -0.5, -0.5, width, height);
+		cairo_rectangle     (cr, frame_clip.x, frame_clip.y, frame_clip.width, frame_clip.height);
+		cairo_clip          (cr);
+	}
+
+	/* Draw frame */
+	if (frame->shadow == MRN_SHADOW_ETCHED_IN || frame->shadow == MRN_SHADOW_ETCHED_OUT)
+	{
+		murrine_set_color_rgb (cr, dark);
+		if (frame->shadow == MRN_SHADOW_ETCHED_IN)
+			murrine_rounded_rectangle (cr, 0, 0, width-2, height-2, widget->roundness, widget->corners);
+		else
+			murrine_rounded_rectangle (cr, 1, 1, width-2, height-2, widget->roundness, widget->corners);
+	}
+	else
+	{
+		murrine_set_color_rgb (cr, border);
+		murrine_rounded_rectangle (cr, 0, 0, width-1, height-1, widget->roundness, widget->corners);
+	}
+	cairo_stroke  (cr);
+	cairo_restore (cr);
+}
+
+static void
+murrine_draw_tab (cairo_t *cr,
+                  const MurrineColors    *colors,
+                  const WidgetParameters *widget,
+                  const TabParameters    *tab,
+                  int x, int y, int width, int height)
+{
+	const float      RADIUS = 3.0;
+	int              corners;
+	double           strip_size;
+	const MurrineRGB *stripe_fill = &colors->spot[1];
+	const MurrineRGB *stripe_border = &colors->spot[2];
+	const MurrineRGB *fill;
+	MurrineRGB       *border1;
+	cairo_pattern_t* pattern;
+
+	fill = &colors->bg[widget->state_type];
+
+	if (!widget->active)
+		border1 = (MurrineRGB*)&colors->shade[5];
+	else
+		border1 = (MurrineRGB*)&colors->shade[4];
+
+	/* Set clip */
+	cairo_rectangle (cr, x, y, width, height);
+	cairo_clip      (cr);
+	cairo_new_path  (cr);
+
+	/* Translate and set line width */
+	cairo_set_line_width (cr, 1.0);
+	cairo_translate      (cr, x+0.5, y+0.5);
+
+	/* Make the tabs slightly bigger than they should be, to create a gap */
+	/* And calculate the strip size too, while you're at it */
+	if (tab->gap_side == MRN_GAP_TOP || tab->gap_side == MRN_GAP_BOTTOM)
+	{
+		height += RADIUS;
+		strip_size = (tab->gap_side == MRN_GAP_TOP ? 2.0/height : 2.0/(height-2));
+
+		if (tab->gap_side == MRN_GAP_TOP)
+		{
+			cairo_translate (cr, 0.0, -3.0); /* gap at the other side */
+			corners = MRN_CORNER_BOTTOMLEFT | MRN_CORNER_BOTTOMRIGHT;
+		}
+		else
+			corners = MRN_CORNER_TOPLEFT | MRN_CORNER_TOPRIGHT;
+	}
+	else
+	{
+		width += RADIUS;
+		strip_size = (tab->gap_side == MRN_GAP_LEFT ? 2.0/width : 2.0/(width-2));
+
+		if (tab->gap_side == MRN_GAP_LEFT)
+		{
+			cairo_translate (cr, -3.0, 0.0); /* gap at the other side */
+			corners = MRN_CORNER_TOPRIGHT | MRN_CORNER_BOTTOMRIGHT;
+		}
+		else
+			corners = MRN_CORNER_TOPLEFT | MRN_CORNER_BOTTOMLEFT;
+	}
+
+	/* Set tab shape */
+	if (widget->roundness < 2)
+		cairo_rectangle (cr, 0, 0, width-1, height-1);
+	else
+		clearlooks_rounded_rectangle (cr, 0, 0, width-1, height-1, widget->roundness, corners);
+
+	/* Draw fill */
+	murrine_set_color_rgb (cr, fill);
+	cairo_fill (cr);
+
+	/* Draw highlight */
+	if (!widget->active)
+	{
+		ShadowParameters shadow;
+
+		shadow.shadow  = MRN_SHADOW_OUT;
+		shadow.corners = widget->corners;
+
+		murrine_draw_highlight_and_shade (cr, colors, &shadow,
+		                                  width,
+		                                  height, widget->roundness-1);
+	}
+
+	if (widget->active)
+	{
+		MurrineRGB shade1, shade2, shade3, shade4;
+
+		MurrineGradients mrn_gradient_custom = widget->mrn_gradient;
+		mrn_gradient_custom.gradient_stop_1 = get_decreased_ratio (widget->mrn_gradient.gradient_stop_1, 3.0);
+		mrn_gradient_custom.gradient_stop_2 = get_decreased_ratio (widget->mrn_gradient.gradient_stop_2, 3.0);
+		mrn_gradient_custom.gradient_stop_3 = get_decreased_ratio (widget->mrn_gradient.gradient_stop_3, 3.0);
+		mrn_gradient_custom.gradient_stop_4 = get_decreased_ratio (widget->mrn_gradient.gradient_stop_4, 3.0);
+
+		double custom_highlight_ratio = widget->highlight_ratio;
+		custom_highlight_ratio = get_decreased_ratio (widget->highlight_ratio, 2.0);
+
+		if (mrn_gradient_custom.gradients)
+		{
+			if (mrn_gradient_custom.has_gradient_stop)
+			{
+				murrine_shade (fill, &shade1, mrn_gradient_custom.gradient_stop_1*custom_highlight_ratio);
+				murrine_shade (fill, &shade2, mrn_gradient_custom.gradient_stop_2*custom_highlight_ratio);
+				murrine_shade (fill, &shade3, mrn_gradient_custom.gradient_stop_3);
+				murrine_shade (fill, &shade4, mrn_gradient_custom.gradient_stop_4);
+			}
+			else
+			{
+				murrine_shade (fill, &shade1, 1.1*custom_highlight_ratio);
+				murrine_shade (fill, &shade2, 1.0*custom_highlight_ratio);
+				murrine_shade (fill, &shade3, 1.0);
+				murrine_shade (fill, &shade4, 1.1);;
+			}
+		}
+		else
+		{
+			murrine_shade (fill, &shade1, 1.0*custom_highlight_ratio);
+			murrine_shade (fill, &shade2, 1.0*custom_highlight_ratio);
+			murrine_shade (fill, &shade3, 1.0);
+			murrine_shade (fill, &shade4, 1.0);
+		}
+
+		switch (tab->gap_side)
+		{
+			case MRN_GAP_TOP:
+				pattern = cairo_pattern_create_linear (0, height-2, 0, 0);
+				break;
+			case MRN_GAP_BOTTOM:
+				pattern = cairo_pattern_create_linear (0, 1, 0, height);
+				break;
+			case MRN_GAP_LEFT:
+				pattern = cairo_pattern_create_linear (width-2, 0, 1, 0);
+				break;
+			case MRN_GAP_RIGHT:
+				pattern = cairo_pattern_create_linear (1, 0, width-2, 0);
+				break;
+		}
+
+		if (widget->roundness < 2)
+			cairo_rectangle (cr, 0, 0, width-1, height-1);
+		else
+			clearlooks_rounded_rectangle (cr, 0, 0, width-1, height-1, widget->roundness, corners);
+
+		cairo_pattern_add_color_stop_rgb (pattern, 0.0, shade1.r, shade1.g, shade1.b);
+		cairo_pattern_add_color_stop_rgb (pattern, 0.4, shade2.r, shade2.g, shade2.b);
+		cairo_pattern_add_color_stop_rgb (pattern, 0.4, shade3.r, shade3.g, shade3.b);
+		cairo_pattern_add_color_stop_rgb (pattern, 1.0, shade4.r, shade4.g, shade4.b);
+		cairo_set_source (cr, pattern);
+		cairo_fill (cr);
+		cairo_pattern_destroy (pattern);
+
+		cairo_set_line_width (cr, 1.0);
+		murrine_set_color_rgba (cr, &colors->shade[0], 0.2);
+
+		if (widget->roundness < 2)
+			cairo_rectangle (cr, 1, 1, width-3, height-3);
+		else
+			clearlooks_rounded_rectangle (cr, 1, 1, width-3, height-3, widget->roundness, corners);
+
+		cairo_stroke (cr);
+	}
+	else
+	{
+		/* Draw shade */
+		switch (tab->gap_side)
+		{
+			case MRN_GAP_TOP:
+				pattern = cairo_pattern_create_linear (0, height-2, 0, 0);
+				break;
+			case MRN_GAP_BOTTOM:
+				pattern = cairo_pattern_create_linear (0, 0, 0, height);
+				break;
+			case MRN_GAP_LEFT:
+				pattern = cairo_pattern_create_linear (width-2, 0, 0, 0);
+				break;
+			case MRN_GAP_RIGHT:
+				pattern = cairo_pattern_create_linear (0, 0, width, 0);
+				break;
+		}
+
+		if (widget->roundness < 2)
+			cairo_rectangle (cr, 0, 0, width-1, height-1);
+		else
+			clearlooks_rounded_rectangle (cr, 0, 0, width-1, height-1, widget->roundness, corners);
+
+		cairo_pattern_add_color_stop_rgb (pattern, 0.0,         stripe_fill->r, stripe_fill->g, stripe_fill->b);
+		cairo_pattern_add_color_stop_rgb (pattern, strip_size,  stripe_fill->r, stripe_fill->g, stripe_fill->b);
+		cairo_pattern_add_color_stop_rgba (pattern, strip_size, fill->r, fill->g, fill->b, 0.0);
+		cairo_set_source (cr, pattern);
+		cairo_fill (cr);
+		cairo_pattern_destroy (pattern);
+	}
+
+	murrine_rounded_rectangle (cr, 0, 0, width-1, height-1, widget->roundness, corners);
+
+	if (widget->active)
+	{
+		murrine_set_color_rgb (cr, border1);
+		cairo_stroke (cr);
+	}
+	else
+	{
+		switch (tab->gap_side)
+		{
+			case MRN_GAP_TOP:
+				pattern = cairo_pattern_create_linear (2, height-2, 2, 2);
+				break;
+			case MRN_GAP_BOTTOM:
+				pattern = cairo_pattern_create_linear (2, 2, 2, height);
+				break;
+			case MRN_GAP_LEFT:
+				pattern = cairo_pattern_create_linear (width-2, 2, 2, 2);
+				break;
+			case MRN_GAP_RIGHT:
+				pattern = cairo_pattern_create_linear (2, 2, width, 2);
+				break;
+		}
+
+		cairo_pattern_add_color_stop_rgb (pattern, 0.0,        stripe_border->r, stripe_border->g, stripe_border->b);
+		cairo_pattern_add_color_stop_rgb (pattern, strip_size, stripe_border->r, stripe_border->g, stripe_border->b);
+		cairo_pattern_add_color_stop_rgb (pattern, strip_size, stripe_border->r, stripe_border->g, stripe_border->b);
+		cairo_pattern_add_color_stop_rgb (pattern, 0.8,        border1->r,       border1->g,       border1->b);
+		cairo_set_source (cr, pattern);
+		cairo_stroke (cr);
+		cairo_pattern_destroy (pattern);
+	}
+}
+
+static void
+murrine_draw_separator (cairo_t *cr,
+                        const MurrineColors       *colors,
+                        const WidgetParameters    *widget,
+                        const SeparatorParameters *separator,
+                        int x, int y, int width, int height)
+{
+	const MurrineRGB *dark   = &colors->shade[3];
+	MurrineRGB highlight;
+	murrine_shade (dark, &highlight, 1.3);
+
+	if (separator->horizontal)
+	{
+		cairo_set_line_width  (cr, 1.0);
+		cairo_translate       (cr, x, y+0.5);
+
+		cairo_move_to         (cr, 0.0,     0.0);
+		cairo_line_to         (cr, width+1, 0.0);
+		murrine_set_color_rgb (cr, dark);
+		cairo_stroke          (cr);
+
+#ifndef HAVE_MACMENU
+		cairo_move_to         (cr, 0.0,   1.0);
+		cairo_line_to         (cr, width, 1.0);
+		murrine_set_color_rgb (cr, &highlight);
+		cairo_stroke          (cr);
+#endif
+	}
+	else
+	{
+		cairo_set_line_width  (cr, 1.0);
+		cairo_translate       (cr, x+0.5, y);
+
+		cairo_move_to         (cr, 0.0, 0.0);
+		cairo_line_to         (cr, 0.0, height);
+		murrine_set_color_rgb (cr, dark);
+		cairo_stroke          (cr);
+
+#ifndef HAVE_MACMENU
+		cairo_move_to         (cr, 1.0, 0.0);
+		cairo_line_to         (cr, 1.0, height);
+		murrine_set_color_rgb (cr, &highlight);
+		cairo_stroke          (cr);
+#endif
+	}
+}
+
+static void
+murrine_draw_combo_separator (cairo_t *cr,
+                              const MurrineColors    *colors,
+                              const WidgetParameters *widget,
+                              int x, int y, int width, int height)
+{
+	const MurrineRGB *dark = &colors->shade[6];
+
+	cairo_set_line_width   (cr, 1.0);
+	cairo_translate        (cr, x+0.5, y);
+
+	cairo_move_to          (cr, 0.0, 0.0);
+	cairo_line_to          (cr, 0.0, height+1);
+	murrine_set_color_rgba (cr, dark, 0.4);
+	cairo_stroke           (cr);
+}
+
+static void
+murrine_draw_list_view_header (cairo_t *cr,
+                               const MurrineColors            *colors,
+                               const WidgetParameters         *widget,
+                               const ListViewHeaderParameters *header,
+                               int x, int y, int width, int height)
+{
+	const MurrineRGB *fill   = &colors->bg[widget->state_type];
+	const MurrineRGB *border = &colors->shade[3];
+	MurrineRGB highlight;
+	murrine_shade (border, &highlight, 1.3);
+
+	cairo_translate (cr, x, y);
+	cairo_set_line_width (cr, 1.0);
+
+	if (header->order == MRN_ORDER_FIRST)
+	{
+		cairo_move_to (cr, 0.5, height-1);
+		cairo_line_to (cr, 0.5, 0.5);
+	}
+	else
+		cairo_move_to (cr, 0.0, 0.5);
+
+	cairo_line_to (cr, width, 0.5);
+	murrine_set_color_rgb (cr, &highlight);
+	cairo_stroke (cr);
+
+	/* Effects */
+	if (header->style > 0)
+	{
+		MurrineRGB highlight_header;
+		murrine_shade (fill, &highlight_header, widget->highlight_ratio);
+		/* Glassy header */
+		if (header->style == 1)
+		{
+			cairo_rectangle (cr, 0, 0, width, height);
+			murrine_set_gradient (cr, fill, widget->mrn_gradient, 0, 0, 0, height, widget->mrn_gradient.gradients, FALSE);
+			/* Glass effect */
+			if (widget->glazestyle > 0)
+			{
+				widget->glazestyle == 2 ? cairo_fill_preserve (cr) : cairo_fill (cr);
+				if (widget->glazestyle < 3)
+					murrine_draw_curved_highlight (cr, 0, width, height);
+				else
+					murrine_draw_curved_highlight_top (cr, 0, width, height);
+			}
+			else
+			{
+				cairo_fill (cr);
+				murrine_draw_flat_highlight (cr, 0 , 0 , width, height);
+			}
+
+			murrine_set_gradient (cr, &highlight_header, widget->mrn_gradient, 0, 0, 0, height, widget->mrn_gradient.gradients, TRUE);
+			cairo_fill (cr);
+
+			if (widget->glazestyle == 4)
+			{
+				murrine_draw_curved_highlight_bottom (cr, 0, width, height);
+				MurrineRGB shadow;
+				murrine_shade (fill, &shadow, 1.0/widget->highlight_ratio);
+				murrine_set_gradient (cr, &shadow, widget->mrn_gradient, 0, 0, 0, height, widget->mrn_gradient.gradients, TRUE);
+				cairo_fill (cr);
+			}
+
+			if (widget->glazestyle == 2)
+			{
+				murrine_draw_innerborder (cr, &highlight, fill, widget->mrn_gradient,
+				                              0.5, 0.5,
+				                              width-2, height-2,
+				                              widget->mrn_gradient.gradients, TRUE,
+				                              widget->glazestyle, widget->roundness, widget->corners);
+			}
+		}
+		/* Raised */
+		else if (header->style == 2)
+		{
+			border = (MurrineRGB*)&colors->shade[4];
+			MurrineRGB shadow_header;
+			murrine_shade (fill, &shadow_header, 0.925);
+
+			if (!widget->mrn_gradient.gradients)
+			{
+				murrine_set_color_rgb (cr, &shadow_header);
+				cairo_rectangle       (cr, 0.0, height-3.0, width, 2.0);
+			}
+			else
+			{
+				cairo_pattern_t *pattern;
+				pattern = cairo_pattern_create_linear (0.0, height-4.0, 0.0, height-1.0);
+				cairo_pattern_add_color_stop_rgba (pattern, 0.0, shadow_header.r, shadow_header.g, shadow_header.b, 0.0);
+				cairo_pattern_add_color_stop_rgb (pattern, 1.0, shadow_header.r, shadow_header.g, shadow_header.b);
+				cairo_set_source      (cr, pattern);
+				cairo_pattern_destroy (pattern);
+				cairo_rectangle       (cr, 0.0, height-4.0, width, 3.0);
+			}
+			cairo_fill (cr);
+		}
+	}
+	/* Draw bottom border */
+	cairo_move_to (cr, 0.0, height-0.5);
+	cairo_line_to (cr, width, height-0.5);
+	murrine_set_color_rgb (cr, border);
+	cairo_stroke (cr);
+
+	/* Draw resize grip */
+	if (header->order != MRN_ORDER_LAST || header->resizable)
+	{
+		if (header->style == 1 && widget->glazestyle > 0)
+		{
+			cairo_set_line_width  (cr, 1.0);
+			cairo_translate       (cr, width-0.5, 0);
+
+			cairo_move_to         (cr, 0, 0);
+			cairo_line_to         (cr, 0, height);
+			murrine_set_color_rgb (cr, border);
+			cairo_stroke          (cr);
+		}
+		else
+		{
+			SeparatorParameters separator;
+			separator.horizontal = FALSE;
+
+			murrine_draw_separator (cr, colors, widget, &separator, width-1.5, 4.0, 2, height-8.0);
+		}
+	}
+}
+
+/* We can't draw transparent things here, since it will be called on the same
+ * surface multiple times, when placed on a handlebox_bin or dockitem_bin */
+static void
+murrine_draw_toolbar (cairo_t *cr,
+                      const MurrineColors    *colors,
+                      const WidgetParameters *widget,
+                      const ToolbarParameters *toolbar,
+                      int x, int y, int width, int height)
+{
+	const MurrineRGB *dark = &colors->shade[3];
+	const MurrineRGB *fill = &colors->bg[0];
+	MurrineRGB top;
+	murrine_shade (dark, &top, 1.3);
+
+	cairo_set_line_width (cr, 1.0);
+	cairo_translate      (cr, x, y);
+	cairo_rectangle (cr, 0, 0, width, height);
+
+#ifdef HAVE_MACMENU
+	murrine_set_color_rgb (cr, fill);
+	cairo_fill (cr);
+#else
+	/* Glass toolbar */
+	if (toolbar->style == 1)
+	{
+		MurrineRGB highlight;
+		murrine_set_gradient (cr, fill, widget->mrn_gradient, 0, 0, 0, height, widget->mrn_gradient.gradients, FALSE);
+		murrine_shade (fill, &highlight, widget->highlight_ratio);
+		/* Glass effect */
+		if (widget->glazestyle > 0)
+		{
+			widget->glazestyle == 2 ? cairo_fill_preserve (cr) : cairo_fill (cr);
+			if (widget->glazestyle < 3)
+				murrine_draw_curved_highlight (cr, 0, width, height);
+			else
+				murrine_draw_curved_highlight_top (cr, 0, width, height);
+		}
+		else
+		{
+			cairo_fill (cr);
+			murrine_draw_flat_highlight (cr, 0, 0, width, height);
+		}
+
+		murrine_set_gradient (cr, &highlight, widget->mrn_gradient, 0, 0, 0, height, widget->mrn_gradient.gradients, TRUE);
+		cairo_fill (cr);
+
+		if (widget->glazestyle == 4)
+		{
+			murrine_draw_curved_highlight_bottom (cr, 0, width, height);
+			MurrineRGB shadow;
+			murrine_shade (fill, &shadow, 1.0/widget->highlight_ratio);
+			murrine_set_color_rgb (cr, &shadow);
+			cairo_fill (cr);
+		}
+	}
+	else if (toolbar->style == 2)
+	{
+		cairo_pattern_t *pattern;
+		MurrineRGB lower;
+		murrine_shade (fill, &lower, 0.95);
+		pattern = cairo_pattern_create_linear (0, 0, 0, height);
+		cairo_pattern_add_color_stop_rgb (pattern, 0.0, fill->r, fill->g, fill->b);
+		cairo_pattern_add_color_stop_rgb (pattern, 1.0, lower.r, lower.g, lower.b);
+		cairo_set_source (cr, pattern);
+		cairo_fill (cr);
+		cairo_pattern_destroy (pattern);
+	}
+	else /* Flat toolbar */
+	{
+		murrine_set_color_rgb (cr, fill);
+		cairo_fill (cr);
+		/* Draw highlight */
+		if (!toolbar->topmost)
+		{
+			cairo_move_to         (cr, 0, 0.5);
+			cairo_line_to         (cr, width, 0.5);
+			murrine_set_color_rgb (cr, &top);
+			cairo_stroke          (cr);
+		}
+	}
+#endif
+
+	/* Draw shadow */
+	cairo_move_to         (cr, 0, height-0.5);
+	cairo_line_to         (cr, width, height-0.5);
+	murrine_set_color_rgb (cr, dark);
+	cairo_stroke          (cr);
+}
+
+static void
+murrine_draw_menuitem (cairo_t *cr,
+                       const MurrineColors    *colors,
+                       const WidgetParameters *widget,
+                       int x, int y, int width, int height,
+                       int menuitemstyle)
+{
+	const MurrineRGB *fill   = &colors->spot[1];
+	const MurrineRGB *border = &colors->spot[2];
+	MurrineRGB highlight;
+	murrine_shade (fill, &highlight, widget->highlight_ratio);
+
+	cairo_translate      (cr, x, y);
+	cairo_set_line_width (cr, 1.0);
+	if (widget->roundness < 2)
+		cairo_rectangle (cr, 0, 0, width, height);
+	else
+		clearlooks_rounded_rectangle (cr, 0, 0, width, height, widget->roundness, widget->corners);
+	murrine_set_gradient (cr, fill, widget->mrn_gradient, 0, 0, 0, height, widget->mrn_gradient.gradients, FALSE);
+
+	/* Striped */
+	if (menuitemstyle == 2)
+	{
+		cairo_fill (cr);
+		double tile_pos = 0;
+		double stroke_width;
+		int    x_step;
+		stroke_width = height*2;
+		cairo_save (cr);
+		x_step = (((float)stroke_width/10));
+		/* Draw strokes */
+		while (tile_pos <= width+x_step-2)
+		{
+			cairo_move_to (cr, stroke_width/2-x_step, 0);
+			cairo_line_to (cr, stroke_width-x_step,   0);
+			cairo_line_to (cr, stroke_width/2-x_step, height);
+			cairo_line_to (cr, -x_step, height);
+			cairo_translate (cr, stroke_width, 0);
+			tile_pos += stroke_width;
+		}
+		murrine_set_color_rgba (cr, border, 0.15);
+		cairo_fill (cr);
+		cairo_restore (cr);
+	}
+	/* Glassy */
+	else if (menuitemstyle != 0)
+	{
+		if (widget->roundness > 1)
+			cairo_clip_preserve (cr);
+		/* Glass effect */
+		if (widget->glazestyle > 0)
+		{
+			widget->glazestyle == 2 ? cairo_fill_preserve (cr) : cairo_fill (cr);
+			if (widget->glazestyle < 3)
+				murrine_draw_curved_highlight (cr, 0, width, height);
+			else
+				murrine_draw_curved_highlight_top (cr, 0, width, height);
+		}
+		else
+		{
+			cairo_fill (cr);
+			murrine_draw_flat_highlight (cr, 0, 0, width, height);
+		}
+		murrine_set_gradient (cr, &highlight, widget->mrn_gradient, 0, 0, 0, height, widget->mrn_gradient.gradients, TRUE);
+		cairo_fill (cr);
+
+		if (widget->glazestyle == 4)
+		{
+			murrine_draw_curved_highlight_bottom (cr, 0, width, height);
+			MurrineRGB shadow;
+			murrine_shade (&colors->spot[1], &shadow, 1.0/widget->highlight_ratio);
+			murrine_set_gradient (cr, &shadow, widget->mrn_gradient, 0, 0, 0, height, widget->mrn_gradient.gradients, TRUE);
+			cairo_fill (cr);
+		}
+
+		if (widget->glazestyle == 2)
+		{
+			murrine_draw_innerborder (cr, &highlight, fill, widget->mrn_gradient,
+			                          1.5, 1.5,
+			                          width-3, height-3,
+			                          widget->mrn_gradient.gradients, TRUE,
+			                          widget->glazestyle, widget->roundness, widget->corners);
+		}
+	}
+	else
+	{
+		cairo_fill (cr);
+		murrine_rounded_rectangle (cr, 0.5, 0.5, width-1, height-1, widget->roundness, widget->corners);
+		murrine_set_color_rgba (cr, border, 0.15);
+		cairo_fill_preserve (cr);
+	}
+	murrine_rounded_rectangle (cr, 0.5, 0.5, width-1, height-1, widget->roundness, widget->corners);
+	murrine_set_color_rgba (cr, border, 0.8);
+	cairo_stroke (cr);
+}
+
+static void
+murrine_draw_scrollbar_trough (cairo_t *cr,
+                               const MurrineColors       *colors,
+                               const WidgetParameters    *widget,
+                               const ScrollBarParameters *scrollbar,
+                               int x, int y, int width, int height)
+{
+	const MurrineRGB *bg     = &colors->shade[scrollbar->stepperstyle < 1 ? 1 : 0];
+	const MurrineRGB *border = &colors->shade[scrollbar->stepperstyle < 1 ? 3 : 4];
+
+	cairo_set_line_width (cr, 1.0);
+
+	if (scrollbar->horizontal)
+	{
+		int tmp = height;
+		rotate_mirror_translate (cr, M_PI/2, x, y, FALSE, FALSE);
+		height = width;
+		width = tmp;
+	}
+	else
+	{
+		cairo_translate (cr, x, y);
+	}
+
+	/* Draw fill */
+	clearlooks_rounded_rectangle (cr, 1, 0, width-2, height, widget->roundness, widget->corners);
+	murrine_set_color_rgba (cr, bg, 0.4);
+	cairo_fill (cr);
+
+	/* Draw border */
+	murrine_rounded_rectangle (cr, 0.5, 0.5, width-1, height-1, widget->roundness, widget->corners);
+	murrine_set_color_rgba (cr, border, 0.8);
+	cairo_stroke (cr);
+}
+
+static void
+murrine_draw_scrollbar_stepper (cairo_t *cr,
+                                const MurrineColors       *colors,
+                                const WidgetParameters    *widget,
+                                const ScrollBarParameters *scrollbar,
+                                int x, int y, int width, int height)
+{
+	const MurrineRGB *fill  = &colors->bg[widget->state_type];
+	MurrineRGB border_normal;
+	MurrineRGB highlight;
+
+	murrine_shade (&colors->shade[6], &border_normal, 0.95);
+	murrine_shade (fill, &highlight, widget->highlight_ratio);
+
+	if (!scrollbar->horizontal)
+		murrine_exchange_axis (cr, &x, &y, &width, &height);
+
+	/* Border color */
+	murrine_mix_color (&border_normal, fill, 0.4, &border_normal);
+
+	cairo_translate (cr, x, y);
+	cairo_set_line_width (cr, 1.0);
+
+	/* Draw the bg */
+	if (widget->roundness < 2)
+		cairo_rectangle (cr, 1, 1, width-2, height-2);
+	else
+		murrine_rounded_rectangle (cr, 0.5, 0.5, width-1, height-1, widget->roundness+1, widget->corners);
+	murrine_set_gradient (cr, fill, widget->mrn_gradient, 1, 1, 0, height-2, widget->mrn_gradient.gradients, FALSE);
+
+	cairo_save (cr);
+
+	int curve_pos = 1;
+	if (widget->glazestyle != 4)
+		curve_pos = 2;
+	/* Draw the glass effect */
+	if (widget->glazestyle > 0)
+	{
+		cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD);
+		widget->glazestyle == 2 ? cairo_fill_preserve (cr) : cairo_fill (cr);
+		if (widget->glazestyle < 3)
+			murrine_draw_curved_highlight (cr, curve_pos, width, height);
+		else
+			murrine_draw_curved_highlight_top (cr, curve_pos, width, height);
+	}
+	else
+	{
+		cairo_fill (cr);
+		murrine_draw_flat_highlight (cr, 1, 1, width-2, height-2);
+	}
+
+	murrine_set_gradient (cr, &highlight, widget->mrn_gradient, 1, 1, 0, height-2, widget->mrn_gradient.gradients, TRUE);
+	cairo_fill (cr);
+
+	if (widget->glazestyle == 4)
+	{
+		murrine_draw_curved_highlight_bottom (cr, curve_pos, width, height);
+		MurrineRGB shadow;
+		murrine_shade (fill, &shadow, 1.0/widget->highlight_ratio);
+		murrine_set_gradient (cr, &shadow, widget->mrn_gradient, 1, 1, 0, height-2, widget->mrn_gradient.gradients, TRUE);
+		cairo_fill (cr);
+	}
+
+	/* Draw the white inner border */
+	if (widget->glazestyle != 4)
+	{
+		murrine_shade (fill, &highlight, widget->innerborder_ratio*widget->highlight_ratio);
+		murrine_draw_innerborder (cr, &highlight, fill, widget->mrn_gradient,
+		                              1.5, 1.5,
+		                              width-3, height-3,
+		                              widget->mrn_gradient.gradients, TRUE,
+		                              widget->glazestyle, widget->roundness, widget->corners);
+	}
+
+	cairo_reset_clip (cr);
+	cairo_restore (cr);
+
+	murrine_set_color_rgb (cr, &border_normal);
+	/* Draw the border */
+	murrine_rounded_rectangle (cr, 0.5, 0.5, width-1, height-1, widget->roundness, widget->corners);
+	cairo_stroke (cr);
+}
+
+static void
+murrine_draw_scrollbar_slider (cairo_t *cr,
+                               const MurrineColors       *colors,
+                               const WidgetParameters    *widget,
+                               const ScrollBarParameters *scrollbar,
+                               int x, int y, int width, int height)
+{
+	if (scrollbar->stepperstyle < 1)
+	{
+		if (scrollbar->junction & MRN_JUNCTION_BEGIN)
+		{
+			if (scrollbar->horizontal)
+			{
+				x -= 1;
+				width += 1;
+			}
+			else
+			{
+				y -= 1;
+				height += 1;
+			}
+		}
+		if (scrollbar->junction & MRN_JUNCTION_END)
+		{
+			if (scrollbar->horizontal)
+				width += 1;
+			else
+				height += 1;
+		}
+	}
+
+	/* Set colors */
+	MurrineRGB fill;
+	if (scrollbar->has_color)
+		fill = scrollbar->color;
+	else
+		fill = colors->bg[0];
+
+	MurrineRGB border;
+	murrine_shade (&colors->shade[6], &border, 0.95);
+	MurrineRGB highlight;
+
+	if (widget->prelight)
+		murrine_shade (&fill, &fill, 1.06);
+
+	murrine_shade (&fill, &highlight, widget->highlight_ratio);
+	/* Draw the border */
+	murrine_mix_color (&border, &fill, 0.4, &border);
+
+	if (scrollbar->horizontal)
+		cairo_translate (cr, x, y);
+
+	else
+	{
+		int tmp = height;
+		rotate_mirror_translate (cr, M_PI/2, x, y, FALSE, FALSE);
+		height = width;
+		width = tmp;
+	}
+
+	cairo_set_line_width (cr, 1.0);
+
+	murrine_rounded_rectangle_fast (cr, 0.5, 0.5, width-1, height-1, widget->corners);
+	murrine_set_color_rgb (cr, &border);
+	cairo_stroke (cr);
+
+	cairo_rectangle (cr, 1, 1, width-2, height-2);
+	murrine_set_gradient (cr, &fill, widget->mrn_gradient, 1, 1, 0, height-2, widget->mrn_gradient.gradients, FALSE);
+
+	/* Draw the glass effect */
+	if (widget->glazestyle > 0)
+	{
+		widget->glazestyle == 2 ? cairo_fill_preserve (cr) : cairo_fill (cr);
+		if (widget->glazestyle < 3)
+			murrine_draw_curved_highlight (cr, 1, width, height);
+		else
+			murrine_draw_curved_highlight_top (cr, 1, width, height);
+	}
+	else
+	{
+		cairo_fill (cr);
+		murrine_draw_flat_highlight (cr, 1, 1, width-2, height-2);
+	}
+
+	murrine_set_gradient (cr, &highlight, widget->mrn_gradient, 1, 1, 0, height-2, widget->mrn_gradient.gradients, TRUE);
+	cairo_fill (cr);
+
+	if (widget->glazestyle == 4)
+	{
+		murrine_draw_curved_highlight_bottom (cr, 1, width, height);
+		MurrineRGB shadow;
+		murrine_shade (&fill, &shadow, 1.0/widget->highlight_ratio);
+		murrine_set_color_rgb (cr, &shadow);
+		cairo_fill (cr);
+	}
+
+	if (widget->glazestyle != 4)
+	{
+		murrine_shade (&fill, &highlight, widget->innerborder_ratio*widget->highlight_ratio);
+		murrine_draw_innerborder (cr, &highlight, &fill, widget->mrn_gradient,
+		                          1.5, 1.5,
+		                          width-3, height-3,
+		                          widget->mrn_gradient.gradients, TRUE,
+		                          widget->glazestyle, 0, MRN_CORNER_NONE);
+	}
+
+	/* Draw the options */
+	MurrineRGB style;
+	if (scrollbar->style > 0)
+		murrine_shade (&fill, &style, 0.55);
+
+	/* Draw the circles */
+	if (scrollbar->style == 1)
+	{
+		int circ_radius = 2;
+		int circ_space = 5;
+		int i;
+		int x1 = circ_space+circ_radius;
+		int y1 = height/2;
+		for (i = circ_space; i < width-circ_space; i += 2*circ_radius+circ_space)
+		{
+			cairo_move_to (cr, i, 1);
+			cairo_arc (cr, x1, y1, circ_radius, 0, M_PI*2);
+
+			x1 += 2*circ_radius+circ_space;
+
+			cairo_close_path (cr);
+			murrine_set_color_rgba (cr, &style, 0.15);
+			cairo_fill (cr);
+		}
+	}
+	if (scrollbar->style > 2)
+	{
+		/* Draw the diagonal strokes */
+		if (scrollbar->style < 5)
+		{
+			cairo_save (cr);
+			cairo_rectangle (cr, 1, 1, width-2, height-2);
+			cairo_clip (cr);
+			cairo_new_path (cr);
+			int counter = -width;
+			cairo_set_line_width (cr, 5); /* stroke width */
+			murrine_set_color_rgba (cr, &style, 0.08);
+			while (counter < height)
+			{
+				cairo_move_to (cr, width, counter);
+				cairo_line_to (cr, 0, counter+width);
+				cairo_stroke  (cr);
+				counter += 12;
+			}
+			cairo_restore (cr);
+		}
+		/* Draw the horizontal strokes */
+		if (scrollbar->style > 4)
+		{
+			int stroke_width = 7;
+			int stroke_space = 5;
+			int i;
+			murrine_set_color_rgba (cr, &style, 0.08);
+			for (i = stroke_space; i < width-stroke_space; i += stroke_width+stroke_space)
+			{
+				cairo_move_to (cr, i, 1);
+				cairo_rel_line_to (cr, 0, height-2);
+				cairo_rel_line_to (cr, stroke_width, 0);
+				cairo_rel_line_to (cr, 0, -(height-2));
+				cairo_fill (cr);
+			}
+		}
+	}
+	/* Draw the handle */
+	if (scrollbar->style > 0 && scrollbar->style % 2 == 0 )
+	{
+		int bar_x = width/2 - 4;
+		cairo_translate (cr, 0.5, 0.5);
+		int i;
+		for (i=0; i<3; i++)
+		{
+			cairo_move_to (cr, bar_x, 4.5);
+			cairo_line_to (cr, bar_x, height-5.5);
+			murrine_set_color_rgb (cr, &border);
+			cairo_stroke (cr);
+
+			bar_x += 3;
+		}
+	}
+}
+
+static void
+murrine_draw_selected_cell (cairo_t *cr,
+                            const MurrineColors    *colors,
+                            const WidgetParameters *widget,
+                            int x, int y, int width, int height)
+{
+	cairo_set_line_cap (cr, CAIRO_LINE_CAP_SQUARE);
+	cairo_set_line_join (cr, CAIRO_LINE_JOIN_MITER);
+
+	MurrineRGB fill;
+	cairo_save (cr);
+
+	cairo_translate (cr, x, y);
+
+	if (widget->focus)
+		fill = colors->base[widget->state_type];
+	else
+		fill = colors->base[GTK_STATE_ACTIVE];
+
+	murrine_set_gradient (cr, &fill, widget->mrn_gradient, 0, 0, 0, height, widget->mrn_gradient.gradients, FALSE);
+	cairo_rectangle (cr, 0, 0, width, height);
+	cairo_fill (cr);
+
+	MurrineRGB border;
+	murrine_shade (&fill, &border, (!widget->mrn_gradient.gradients ? 0.9 : 0.95));
+
+	cairo_move_to  (cr, 0, 0.5);
+	cairo_rel_line_to (cr, width, 0);
+	cairo_move_to (cr, 0, height-0.5);
+	cairo_rel_line_to (cr, width, 0);
+
+	murrine_set_color_rgb (cr, &border);
+	cairo_stroke (cr);
+
+	cairo_restore (cr);
+}
+
+static void
+murrine_draw_statusbar (cairo_t *cr,
+                        const MurrineColors    *colors,
+                        const WidgetParameters *widget,
+                        int x, int y, int width, int height)
+{
+	const MurrineRGB *dark   = &colors->shade[3];
+	MurrineRGB highlight;
+	murrine_shade (dark, &highlight, 1.3);
+
+	cairo_set_line_width  (cr, 1);
+	cairo_translate       (cr, x, y+0.5);
+	cairo_move_to         (cr, 0, 0);
+	cairo_line_to         (cr, width, 0);
+	murrine_set_color_rgb (cr, dark);
+	cairo_stroke          (cr);
+
+	cairo_translate       (cr, 0, 1);
+	cairo_move_to         (cr, 0, 0);
+	cairo_line_to         (cr, width, 0);
+	murrine_set_color_rgb (cr, &highlight);
+	cairo_stroke          (cr);
+}
+
+static void
+murrine_draw_menu_frame (cairo_t *cr,
+                         const MurrineColors    *colors,
+                         const WidgetParameters *widget,
+                         int x, int y, int width, int height,
+                         int menustyle)
+{
+	const MurrineRGB *border = &colors->shade[5];
+
+	cairo_translate       (cr, x, y);
+	cairo_set_line_width  (cr, 1);
+	cairo_rectangle       (cr, 0.5, 0.5, width-1, height-1);
+	murrine_set_color_rgb (cr, border);
+	cairo_stroke          (cr);
+
+	if (menustyle == 1)
+	{
+		MurrineRGB *fill = (MurrineRGB*)&colors->spot[1];
+		MurrineRGB border2;
+		murrine_shade (fill, &border2, 0.5);
+
+		cairo_rectangle (cr, 0.5, 0.5, 3, height-1);
+		murrine_set_color_rgb (cr, &border2);
+		cairo_stroke_preserve (cr);
+
+		murrine_set_color_rgb (cr, fill);
+		cairo_fill (cr);
+	}
+}
+
+static void
+murrine_draw_tooltip (cairo_t *cr,
+                      const MurrineColors    *colors,
+                      const WidgetParameters *widget,
+                      int x, int y, int width, int height)
+{
+	MurrineRGB border, highlight;
+
+	MurrineGradients mrn_gradient_custom = widget->mrn_gradient;
+
+	mrn_gradient_custom.gradient_stop_1 = get_decreased_ratio (widget->mrn_gradient.gradient_stop_1, 2.0);
+	mrn_gradient_custom.gradient_stop_2 = get_decreased_ratio (widget->mrn_gradient.gradient_stop_2, 2.0);
+	mrn_gradient_custom.gradient_stop_3 = get_decreased_ratio (widget->mrn_gradient.gradient_stop_3, 2.0);
+	mrn_gradient_custom.gradient_stop_4 = get_decreased_ratio (widget->mrn_gradient.gradient_stop_4, 2.0);
+
+	murrine_shade (&colors->bg[widget->state_type], &border, 0.6);
+	murrine_shade (&colors->bg[widget->state_type], &highlight, 1.0);
+
+	cairo_save (cr);
+
+	cairo_translate      (cr, x, y);
+	cairo_set_line_width (cr, 1.0);
+
+	murrine_set_gradient (cr, &colors->bg[widget->state_type], mrn_gradient_custom, 0, 0, 0, height, widget->mrn_gradient.gradients, FALSE);
+	cairo_rectangle (cr, 0, 0, width, height);
+	cairo_fill (cr);
+
+	murrine_set_gradient (cr, &highlight, mrn_gradient_custom, 0, 0, 0, height, widget->mrn_gradient.gradients, TRUE);
+	cairo_rectangle (cr, 0, 0, width, height/2);
+	cairo_fill (cr);
+
+	murrine_set_color_rgb (cr, &border);
+	cairo_rectangle (cr, 0.5, 0.5, width-1, height-1);
+	cairo_stroke (cr);
+
+	cairo_restore (cr);
+}
+
+static void
+murrine_draw_handle (cairo_t *cr,
+                     const MurrineColors    *colors,
+                     const WidgetParameters *widget,
+                     const HandleParameters *handle,
+                     int x, int y, int width, int height)
+{
+	const MurrineRGB *dark  = &colors->shade[4];
+
+	int bar_height;
+	int bar_width  = 4;
+	int i, bar_y = 1;
+	int num_bars, bar_spacing;
+	num_bars    = 3;
+	bar_spacing = 3;
+	bar_height = num_bars * bar_spacing;
+
+	if (handle->horizontal)
+	{
+		int tmp = height;
+		rotate_mirror_translate (cr, M_PI/2, x + 0.5 + width/2 - bar_height/2, y + height/2 - bar_width/2, FALSE, FALSE);
+		height = width;
+		width = tmp;
+	}
+	else
+	{
+		cairo_translate (cr, x + width/2 - bar_width/2, y + height/2 - bar_height/2 + 0.5);
+	}
+
+	cairo_set_line_width (cr, 1.0);
+
+	for (i=0; i<num_bars; i++)
+	{
+		cairo_move_to (cr, 0, bar_y);
+		cairo_line_to (cr, bar_width, bar_y);
+		murrine_set_color_rgb (cr, dark);
+		cairo_stroke (cr);
+
+		bar_y += bar_spacing;
+	}
+}
+
+static void
+murrine_draw_normal_arrow (cairo_t *cr,
+                           const MurrineRGB *color,
+                           double x, double y, double width, double height)
+{
+	double arrow_width;
+	double arrow_height;
+	double line_width_2;
+
+	cairo_save (cr);
+
+	arrow_width = MIN (height * 2.0 + MAX (1.0, ceil (height * 2.0 / 6.0 * 2.0) / 2.0) / 2.0, width);
+	line_width_2 = MAX (1.0, ceil (arrow_width / 6.0 * 2.0) / 2.0) / 2.0;
+	arrow_height = arrow_width / 2.0 + line_width_2;
+
+	cairo_translate (cr, x, y - arrow_height / 2.0);
+
+	cairo_move_to (cr, -arrow_width / 2.0, line_width_2);
+	cairo_line_to (cr, -arrow_width / 2.0 + line_width_2, 0);
+	/* cairo_line_to (cr, 0, arrow_height - line_width_2); */
+	cairo_arc_negative (cr, 0, arrow_height - 2*line_width_2 - 2*line_width_2 * sqrt(2), 2*line_width_2, M_PI_2 + M_PI_4, M_PI_4);
+	cairo_line_to (cr, arrow_width / 2.0 - line_width_2, 0);
+	cairo_line_to (cr, arrow_width / 2.0, line_width_2);
+	cairo_line_to (cr, 0, arrow_height);
+	cairo_close_path (cr);
+
+	murrine_set_color_rgb (cr, color);
+	cairo_fill (cr);
+
+	cairo_restore (cr);
+}
+
+static void
+murrine_draw_combo_arrow (cairo_t *cr,
+                          const MurrineRGB *color,
+                          double x, double y, double width, double height)
+{
+	double arrow_width = MIN (height * 2 / 3.0, width);
+	double arrow_height = arrow_width / 2.0;
+	double gap_size = 1.0 * arrow_height;
+
+	cairo_save (cr);
+	cairo_translate (cr, x, y - (arrow_height + gap_size) / 2.0);
+	cairo_rotate (cr, M_PI);
+	murrine_draw_normal_arrow (cr, color, 0, 0, arrow_width, arrow_height);
+	cairo_restore (cr);
+
+	murrine_draw_normal_arrow (cr, color, x, y + (arrow_height + gap_size) / 2.0, arrow_width, arrow_height);
+}
+
+static void
+_murrine_draw_arrow (cairo_t *cr,
+                     const MurrineRGB *color,
+                     MurrineDirection dir, MurrineArrowType type,
+                     double x, double y, double width, double height)
+{
+	double rotate;
+
+	if (dir == MRN_DIRECTION_LEFT)
+		rotate = M_PI*1.5;
+	else if (dir == MRN_DIRECTION_RIGHT)
+		rotate = M_PI*0.5;
+	else if (dir == MRN_DIRECTION_UP)
+		rotate = M_PI;
+	else if (dir == MRN_DIRECTION_DOWN)
+		rotate = 0;
+	else
+		return;
+
+	if (type == MRN_ARROW_NORMAL)
+	{
+		cairo_translate (cr, x, y);
+		cairo_rotate (cr, -rotate);
+		murrine_draw_normal_arrow (cr, color, 0, 0, width, height);
+	}
+	else if (type == MRN_ARROW_COMBO)
+	{
+		cairo_translate (cr, x, y);
+		murrine_draw_combo_arrow (cr, color, 0, 0, width, height);
+	}
+}
+
+static void
+murrine_draw_arrow (cairo_t *cr,
+                    const MurrineColors    *colors,
+                    const WidgetParameters *widget,
+                    const ArrowParameters  *arrow,
+                    int x, int y, int width, int height)
+{
+	MurrineRGB color = colors->fg[widget->state_type];
+	murrine_mix_color (&color, &colors->bg[widget->state_type], 0.2, &color);
+	gdouble tx, ty;
+
+	tx = x + width/2.0;
+	ty = y + height/2.0;
+
+	if (widget->disabled)
+	{
+		_murrine_draw_arrow (cr, &colors->shade[0],
+		                     arrow->direction, arrow->type,
+		                     tx+0.5, ty+0.5, width, height);
+	}
+
+	cairo_identity_matrix (cr);
+
+	_murrine_draw_arrow (cr, &color, arrow->direction, arrow->type,
+	                     tx, ty, width, height);
+}
+
+static void
+murrine_draw_radiobutton (cairo_t * cr,
+                          const MurrineColors    *colors,
+                          const WidgetParameters *widget,
+                          const OptionParameters *status,
+                          int x, int y, int width, int height,
+                          double trans)
+{
+	const MurrineRGB *border;
+	const MurrineRGB *dot;
+
+	width = height = 15;
+
+	if (widget->state_type == GTK_STATE_INSENSITIVE)
+	{
+		border = &colors->shade[3];
+		dot    = &colors->shade[3];
+	}
+	else
+	{
+		border = &colors->shade[5];
+		if (status->draw_bullet)
+			border = &colors->spot[2];
+		dot    = &colors->text[widget->state_type];
+	}
+	MurrineRGB shadow;
+	murrine_shade (border, &shadow, 0.9);
+
+	cairo_translate (cr, x, y);
+
+	cairo_set_line_width (cr, 2);
+	cairo_arc (cr, 7, 7, 6, 0, M_PI*2);
+	murrine_set_color_rgba (cr, &shadow, 0.15);
+	cairo_stroke (cr);
+
+	cairo_set_line_width (cr, 1.0);
+
+	cairo_arc (cr, 7, 7, 5.5, 0, M_PI*2);
+
+	if (widget->state_type != GTK_STATE_INSENSITIVE)
+	{
+		const MurrineRGB *bg = &colors->base[0];
+		if (status->draw_bullet)
+			bg = &colors->spot[1];
+		if (widget->glazestyle != 2)
+		{
+			MurrineRGB highlight;
+			murrine_shade (bg, &highlight, widget->highlight_ratio);
+			murrine_set_gradient (cr, &highlight, widget->mrn_gradient, 0, 0, 0, 14, widget->mrn_gradient.gradients, FALSE);
+		}
+		else
+			murrine_set_gradient (cr, bg, widget->mrn_gradient, 0, 0, 0, 14, widget->mrn_gradient.gradients, FALSE);
+		cairo_fill_preserve (cr);
+	}
+
+	murrine_set_color_rgb (cr, border);
+	cairo_stroke (cr);
+
+	cairo_arc (cr, 7, 7, 5, 0, M_PI*2);
+	cairo_clip (cr);
+
+	if (widget->state_type != GTK_STATE_INSENSITIVE)
+	{
+		const MurrineRGB *bg = &colors->base[0];
+		if (status->draw_bullet)
+			bg = &colors->spot[1];
+
+		cairo_rectangle (cr, 0, 7, width, height);
+		if (widget->glazestyle == 2)
+		{
+			MurrineRGB highlight;
+			murrine_shade (bg, &highlight, widget->highlight_ratio);
+			murrine_set_gradient (cr, &highlight, widget->mrn_gradient, 0, 0, 0, 14, widget->mrn_gradient.gradients, FALSE);
+		}
+		else
+			murrine_set_gradient (cr, bg, widget->mrn_gradient, 0, 0, 0, 14, widget->mrn_gradient.gradients, FALSE);
+		cairo_fill (cr);
+	}
+
+	/* inconsistent state is missing? */
+	if (status->draw_bullet)
+	{
+		cairo_arc (cr, 7, 7, 2, 0, M_PI*2);
+		/* murrine_set_color_rgb (cr, dot); */
+		murrine_set_color_rgba (cr, dot, trans);
+		cairo_fill (cr);
+	}
+
+	cairo_restore (cr);
+}
+
+static void
+murrine_draw_checkbox (cairo_t * cr,
+                       const MurrineColors    *colors,
+                       const WidgetParameters *widget,
+                       const OptionParameters *status,
+                       int x, int y, int width, int height,
+                       double trans)
+{
+	const MurrineRGB *border;
+	const MurrineRGB *dot;
+
+	width = height = 13;
+
+	if (widget->state_type == GTK_STATE_INSENSITIVE)
+	{
+		border = &colors->shade[3];
+		dot    = &colors->shade[3];
+	}
+	else
+	{
+		border = &colors->shade[5];
+		if (status->draw_bullet)
+			border = &colors->spot[2];
+		dot    = &colors->text[widget->state_type];
+	}
+	MurrineRGB shadow;
+	murrine_shade (border, &shadow, 0.9);
+
+	cairo_translate (cr, x, y);
+	cairo_set_line_width (cr, 1.0);
+
+	if (widget->xthickness > 2 && widget->ythickness > 2)
+	{
+		cairo_rectangle (cr, 0.5, 0.5, width-1, height-1);
+		murrine_set_color_rgba (cr, &shadow, 0.15);
+		cairo_stroke (cr);
+
+		/* Draw the rectangle for the checkbox itself */
+		cairo_rectangle (cr, 1.5, 1.5, width-3, height-3);
+	}
+	else
+	{
+		cairo_rectangle (cr, 0.5, 0.5, width-1, height-1);
+	}
+
+
+	if (widget->state_type != GTK_STATE_INSENSITIVE)
+	{
+		const MurrineRGB *bg = &colors->base[0];
+		if (status->draw_bullet)
+			bg = &colors->spot[1];
+
+		if (widget->glazestyle == 2)
+		{
+			MurrineRGB highlight;
+			murrine_shade (bg, &highlight, widget->highlight_ratio);
+			murrine_set_gradient (cr, &highlight, widget->mrn_gradient, 0, 0, 0, 14, widget->mrn_gradient.gradients, FALSE);
+		}
+		else
+			murrine_set_gradient (cr, bg, widget->mrn_gradient, 0, 0, 0, 14, widget->mrn_gradient.gradients, FALSE);
+		cairo_fill_preserve (cr);
+	}
+
+	murrine_set_color_rgb (cr, border);
+	cairo_stroke (cr);
+
+	if (widget->state_type != GTK_STATE_INSENSITIVE)
+	{
+		const MurrineRGB *bg = &colors->base[0];
+		if (status->draw_bullet)
+			bg = &colors->spot[1];
+
+		MurrineRGB highlight;
+		murrine_shade (bg, &highlight, widget->highlight_ratio);
+		if (widget->xthickness > 2 && widget->ythickness > 2)
+			cairo_rectangle (cr, 2, 2, width-4, (height-4)/2);
+		else
+			cairo_rectangle (cr, 1, 1, width-2, (height-2)/2);
+
+		if (widget->glazestyle != 2)
+		{
+			MurrineRGB highlight;
+			murrine_shade (bg, &highlight, widget->highlight_ratio);
+			murrine_set_gradient (cr, &highlight, widget->mrn_gradient, 0, 0, 0, 14, widget->mrn_gradient.gradients, FALSE);
+		}
+		else
+			murrine_set_gradient (cr, bg, widget->mrn_gradient, 0, 0, 0, 14, widget->mrn_gradient.gradients, FALSE);
+		cairo_fill (cr);
+	}
+
+	cairo_scale (cr, width / 13.0, height / 13.0);
+	if (status->draw_bullet)
+	{
+		if (status->inconsistent) /* Inconsistent */
+		{
+			cairo_set_line_width (cr, 2.0);
+			cairo_move_to (cr, 3, height*0.5);
+			cairo_line_to (cr, width-3, height*0.5);
+		}
+		else
+		{
+			cairo_translate (cr, -2, 0);
+		/*
+			if (widget && widget->parent && GTK_IS_MENU(widget->parent))
+				cairo_translate (cr, 0, 0);
+		*/
+			cairo_move_to (cr, 4, 8);
+			cairo_rel_line_to (cr, 5, 4);
+			cairo_rel_curve_to (cr, 1.4, -5, -1, -1, 5.7, -12.5);
+			cairo_rel_curve_to (cr, -4, 4, -4, 4, -6.7, 9.3);
+			cairo_rel_line_to (cr, -2.3, -2.5);
+		}
+
+		murrine_set_color_rgba (cr, dot, trans);
+		cairo_fill (cr);
+	}
+}
+
+static void
+murrine_draw_resize_grip (cairo_t *cr,
+                          const MurrineColors        *colors,
+                          const WidgetParameters     *widget,
+                          const ResizeGripParameters *grip,
+                          int x, int y, int width, int height)
+{
+	const MurrineRGB *dark   = &colors->shade[3];
+	MurrineRGB highlight;
+	murrine_shade (dark, &highlight, 1.3);
+	int lx, ly;
+
+	cairo_set_line_width (cr, 1.0);
+
+	for (ly=0; ly<4; ly++) /* vertically, four rows of dots */
+	{
+		for (lx=0; lx<=ly; lx++) /* horizontally */
+		{
+			int ny = (3.5-ly) * 3;
+			int nx = lx * 3;
+
+			murrine_set_color_rgb (cr, &highlight);
+			cairo_rectangle (cr, x+width-nx-1, y+height-ny-1, 2, 2);
+			cairo_fill (cr);
+
+			murrine_set_color_rgb (cr, dark);
+			cairo_rectangle (cr, x+width-nx-1, y+height-ny-1, 1, 1);
+			cairo_fill (cr);
+		}
+	}
+}
+
+void
+murrine_register_style_murrine (MurrineStyleFunctions *functions)
+{
+	g_assert (functions);
+
+	functions->draw_button             = murrine_draw_button;
+	functions->draw_scale_trough       = murrine_draw_scale_trough;
+	functions->draw_progressbar_trough = murrine_draw_progressbar_trough;
+	functions->draw_progressbar_fill   = murrine_draw_progressbar_fill;
+	functions->draw_entry              = murrine_draw_entry;
+	functions->draw_slider_handle      = murrine_draw_slider_handle;
+	functions->draw_spinbutton_down    = murrine_draw_spinbutton_down;
+	functions->draw_optionmenu         = murrine_draw_optionmenu;
+	functions->draw_combo_separator    = murrine_draw_combo_separator;
+	functions->draw_menubar	           = murrine_draw_menubar;
+	functions->draw_tab                = murrine_draw_tab;
+	functions->draw_frame              = murrine_draw_frame;
+	functions->draw_separator          = murrine_draw_separator;
+	functions->draw_list_view_header   = murrine_draw_list_view_header;
+	functions->draw_toolbar            = murrine_draw_toolbar;
+	functions->draw_tooltip            = murrine_draw_tooltip;
+	functions->draw_menuitem           = murrine_draw_menuitem;
+	functions->draw_selected_cell      = murrine_draw_selected_cell;
+	functions->draw_scrollbar_stepper  = murrine_draw_scrollbar_stepper;
+	functions->draw_scrollbar_slider   = murrine_draw_scrollbar_slider;
+	functions->draw_scrollbar_trough   = murrine_draw_scrollbar_trough;
+	functions->draw_statusbar          = murrine_draw_statusbar;
+	functions->draw_menu_frame         = murrine_draw_menu_frame;
+	functions->draw_tooltip            = murrine_draw_tooltip;
+	functions->draw_handle             = murrine_draw_handle;
+	functions->draw_resize_grip        = murrine_draw_resize_grip;
+	functions->draw_arrow              = murrine_draw_arrow;
+	functions->draw_checkbox           = murrine_draw_checkbox;
+	functions->draw_radiobutton        = murrine_draw_radiobutton;
+}

Added: trunk/src/murrine_draw.h
==============================================================================
--- (empty file)
+++ trunk/src/murrine_draw.h	Mon Feb 11 23:01:49 2008
@@ -0,0 +1,35 @@
+/* Murrine theme engine
+ * Copyright (C) 2007 Andrea Cimitan
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ */
+
+#ifndef MURRINE_DRAW_H
+#define MURRINE_DRAW_H
+
+#include "murrine_style.h"
+#include "murrine_types.h"
+
+#include <gtk/gtk.h>
+#include <gdk/gdk.h>
+
+#include <cairo.h>
+
+G_GNUC_INTERNAL void murrine_register_style_murrine (MurrineStyleFunctions *functions);
+G_GNUC_INTERNAL void murrine_register_style_rgba (MurrineStyleFunctions *functions);
+
+#endif /* MURRINE_DRAW_H */

Added: trunk/src/murrine_draw_rgba.c
==============================================================================
--- (empty file)
+++ trunk/src/murrine_draw_rgba.c	Mon Feb 11 23:01:49 2008
@@ -0,0 +1,1959 @@
+/* Murrine theme engine
+ * Copyright (C) 2007 Andrea Cimitan
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include "murrine_draw.h"
+#include "murrine_style.h"
+#include "murrine_types.h"
+
+#include "support.h"
+#include "cairo-support.h"
+
+#include <cairo.h>
+
+#define M_PI 3.14159265358979323846
+
+static void
+murrine_draw_inset (cairo_t          *cr,
+                    const MurrineRGB *bg_color,
+                    double x, double y, double w, double h,
+                    double radius, uint8 corners)
+{
+	MurrineRGB highlight, shadow;
+
+	murrine_shade (bg_color, &highlight, 1.15);
+	murrine_shade (bg_color, &shadow, 0.4);
+
+	/* highlight */
+	cairo_move_to (cr, x + w + (radius * -0.2928932188), y - (radius * -0.2928932188)); /* 0.2928932... 1-sqrt(2)/2 gives middle of curve */
+
+	if (corners & MRN_CORNER_TOPRIGHT)
+		cairo_arc (cr, x + w - radius, y + radius, radius, M_PI * 1.75, M_PI * 2);
+	else
+		cairo_line_to (cr, x + w, y);
+
+	if (corners & MRN_CORNER_BOTTOMRIGHT)
+		cairo_arc (cr, x + w - radius, y + h - radius, radius, 0, M_PI * 0.5);
+	else
+		cairo_line_to (cr, x + w, y + h);
+
+	if (corners & MRN_CORNER_BOTTOMLEFT)
+		cairo_arc (cr, x + radius, y + h - radius, radius, M_PI * 0.5, M_PI * 0.75);
+	else
+		cairo_line_to (cr, x, y + h);
+
+	murrine_set_color_rgba (cr, &highlight, 0.48);
+	cairo_stroke (cr);
+
+	/* shadow */
+	cairo_move_to (cr, x + (radius * 0.2928932188), y + h + (radius * -0.2928932188));
+
+	if (corners & MRN_CORNER_BOTTOMLEFT)
+		cairo_arc (cr, x + radius, y + h - radius, radius, M_PI * 0.75, M_PI);
+	else
+		cairo_line_to (cr, x, y + h);
+
+	if (corners & MRN_CORNER_TOPLEFT)
+		cairo_arc (cr, x + radius, y + radius, radius, M_PI, M_PI * 1.5);
+	else
+		cairo_line_to (cr, x, y);
+
+	if (corners & MRN_CORNER_TOPRIGHT)
+	    cairo_arc (cr, x + w - radius, y + radius, radius, M_PI * 1.5, M_PI * 1.75);
+	else
+		cairo_line_to (cr, x + w, y);
+
+	murrine_set_color_rgba (cr, &shadow, 0.12);
+	cairo_stroke (cr);
+}
+
+static void
+murrine_draw_highlight_and_shade (cairo_t *cr,
+                                  const MurrineColors *colors,
+                                  const ShadowParameters *widget,
+                                  int width, int height, int radius)
+{
+	MurrineRGB highlight;
+	MurrineRGB shadow;
+	uint8 corners = widget->corners;
+	double x = 1.0;
+	double y = 1.0;
+
+	murrine_shade (&colors->bg[0], &highlight, 1.15);
+	murrine_shade (&colors->bg[0], &shadow, 0.4);
+
+	width  -= 3;
+	height -= 3;
+
+	cairo_save (cr);
+
+	/* Top/Left highlight */
+	if (corners & MRN_CORNER_BOTTOMLEFT)
+		cairo_move_to (cr, x, y+height-radius);
+	else
+		cairo_move_to (cr, x, y+height);
+
+	murrine_rounded_corner (cr, x, y, radius, corners & MRN_CORNER_TOPLEFT);
+
+	if (corners & MRN_CORNER_TOPRIGHT)
+		cairo_line_to (cr, x+width-radius, y);
+	else
+		cairo_line_to (cr, x+width, y);
+
+	if (widget->shadow & MRN_SHADOW_OUT)
+		murrine_set_color_rgba (cr, &highlight, 0.5);
+	else
+		murrine_set_color_rgba (cr, &shadow, 0.13);
+
+	cairo_stroke (cr);
+
+	/* Bottom/Right highlight -- this includes the corners */
+	cairo_move_to (cr, x+width-radius, y); /* topright and by radius to the left */
+	murrine_rounded_corner (cr, x+width, y, radius, corners & MRN_CORNER_TOPRIGHT);
+	murrine_rounded_corner (cr, x+width, y+height, radius, corners & MRN_CORNER_BOTTOMRIGHT);
+	murrine_rounded_corner (cr, x, y+height, radius, corners & MRN_CORNER_BOTTOMLEFT);
+
+	if (widget->shadow & MRN_SHADOW_OUT)
+		murrine_set_color_rgba (cr, &shadow, 0.13);
+	else
+		murrine_set_color_rgba (cr, &highlight, 0.5);
+
+	cairo_stroke (cr);
+
+	cairo_restore (cr);
+}
+
+static void
+murrine_rgba_draw_button (cairo_t *cr,
+                          const MurrineColors    *colors,
+                          const WidgetParameters *widget,
+                          int x, int y, int width, int height,
+                          boolean horizontal)
+{
+	double xoffset = 0, yoffset = 0;
+	MurrineRGB fill = colors->bg[widget->state_type];
+	MurrineRGB border_disabled = colors->shade[6];
+	MurrineRGB border_normal;
+	MurrineRGB highlight;
+
+	double custom_highlight_ratio = widget->highlight_ratio;
+	MurrineGradients mrn_gradient_custom = widget->mrn_gradient;
+
+	if (widget->disabled)
+	{
+		mrn_gradient_custom.gradient_stop_1 = get_decreased_ratio (widget->mrn_gradient.gradient_stop_1, 3.0);
+		mrn_gradient_custom.gradient_stop_2 = get_decreased_ratio (widget->mrn_gradient.gradient_stop_2, 3.0);
+		mrn_gradient_custom.gradient_stop_3 = get_decreased_ratio (widget->mrn_gradient.gradient_stop_3, 3.0);
+		mrn_gradient_custom.gradient_stop_4 = get_decreased_ratio (widget->mrn_gradient.gradient_stop_4, 3.0);
+		custom_highlight_ratio = get_decreased_ratio (widget->highlight_ratio, 2.0);
+	}
+
+	if (widget->is_default)
+		murrine_mix_color (&fill, &colors->spot[1], 0.2, &fill);
+
+	if (!horizontal)
+		murrine_exchange_axis (cr, &x, &y, &width, &height);
+
+	murrine_shade (&colors->shade[8], &border_normal, 0.95);
+	murrine_shade (&fill, &highlight, custom_highlight_ratio);
+
+	cairo_translate (cr, x, y);
+	cairo_set_line_width (cr, 1.0);
+
+	if (widget->xthickness > 1)
+		xoffset = 1;
+	if (widget->ythickness > 1)
+		yoffset = 1;
+
+	if (!widget->active)
+	{
+		murrine_rounded_rectangle (cr, xoffset, yoffset, width-(xoffset*2), height-(yoffset*2), widget->roundness, widget->corners);
+		murrine_set_color_rgba (cr, widget->disabled ? &border_disabled : &border_normal, 0.16);
+		cairo_stroke (cr);
+	}
+
+	murrine_mix_color (widget->disabled ? &border_disabled : &border_normal , &widget->parentbg, 0.2,
+	                   widget->disabled ? &border_disabled : &border_normal);
+
+	murrine_mix_color (widget->disabled ? &border_disabled : &border_normal , &fill, 0.25,
+	                   widget->disabled ? &border_disabled : &border_normal);
+
+	/* Default button */
+	if (widget->is_default)
+	{
+		murrine_rounded_rectangle (cr, xoffset, yoffset, width-(xoffset*2), height-(yoffset*2), widget->roundness, widget->corners);
+		murrine_set_color_rgba (cr, &colors->spot[1], 0.6);
+		cairo_stroke (cr);
+		murrine_shade (&border_normal, &border_normal, 0.8);
+	}
+
+	/* Draw the bg */
+	if (widget->roundness < 2)
+		cairo_rectangle (cr, xoffset + 1, yoffset + 1, width-(xoffset*2)-2, height-(yoffset*2)-2);
+	else
+		clearlooks_rounded_rectangle (cr, xoffset+0.5, yoffset+0.5, width-(xoffset*2)-1, height-(yoffset*2)-1, widget->roundness+1, widget->corners);
+	murrine_set_gradient (cr, &fill, mrn_gradient_custom, xoffset+1, yoffset+1, 0, height-(yoffset*2)-2, widget->mrn_gradient.gradients, FALSE);
+
+	cairo_save (cr);
+	cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+
+	if (widget->roundness > 1)
+		cairo_clip_preserve (cr);
+
+	int curve_pos = 1;
+	if (widget->glazestyle != 4)
+		curve_pos = 2;
+
+	/* Draw the glass effect */
+	if (widget->glazestyle > 0)
+	{
+		cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD);
+		widget->glazestyle == 2 ? cairo_fill_preserve (cr) : cairo_fill (cr);
+		if (widget->glazestyle < 3)
+			murrine_draw_curved_highlight (cr, curve_pos, width, height);
+		else
+			murrine_draw_curved_highlight_top (cr, curve_pos, width, height);
+	}
+	else
+	{
+		cairo_fill (cr);
+		murrine_draw_flat_highlight (cr, xoffset + 1, yoffset + 1, width-(xoffset*2)-2, height-(yoffset*2)-2);
+	}
+
+	murrine_set_gradient (cr, &highlight, mrn_gradient_custom, xoffset+1, yoffset+1, 0, height-(yoffset*2)-2, widget->mrn_gradient.gradients, TRUE);
+	cairo_fill (cr);
+
+	if (widget->glazestyle == 4)
+	{
+		murrine_draw_curved_highlight_bottom (cr, curve_pos, width, height);
+		MurrineRGB shadow;
+		murrine_shade (&fill, &shadow, 1.0/custom_highlight_ratio);
+		murrine_set_gradient (cr, &shadow, mrn_gradient_custom, xoffset+1, yoffset+1, 0, height-(yoffset*2)-2, widget->mrn_gradient.gradients, TRUE);
+		cairo_fill (cr);
+	}
+
+	cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
+
+	/* Draw the white inner border */
+	if (widget->glazestyle != 4 && !widget->active)
+	{
+		murrine_shade (&fill, &highlight, widget->innerborder_ratio*custom_highlight_ratio);
+		if (horizontal)
+		{
+			murrine_draw_innerborder (cr, &highlight, &fill, mrn_gradient_custom,
+			                          xoffset + 1.5, yoffset + 1.5,
+			                          width-(xoffset*2)-3, height-(yoffset*2)-3,
+			                          widget->mrn_gradient.gradients, horizontal,
+			                          widget->glazestyle, widget->roundness, widget->corners);
+		}
+		else
+		{
+			murrine_exchange_axis (cr, &x, &y, &width, &height);
+			murrine_draw_innerborder (cr, &highlight, &fill, mrn_gradient_custom,
+			                          xoffset + 1.5, yoffset + 1.5,
+			                          width-(xoffset*2)-3, height-(yoffset*2)-3,
+			                          widget->mrn_gradient.gradients, horizontal,
+			                          widget->glazestyle, widget->roundness, widget->corners);
+			murrine_exchange_axis (cr, &x, &y, &width, &height);
+		}
+	}
+
+	cairo_restore (cr);
+
+	/* Draw pressed button shadow */
+	if (widget->active)
+	{
+		cairo_pattern_t *pattern;
+		MurrineRGB shadow;
+
+		murrine_shade (&fill, &shadow, 0.94);
+
+		cairo_save (cr);
+
+		if (widget->roundness < 2)
+			cairo_rectangle (cr, xoffset + 1, yoffset + 1, width-(xoffset*2)-2, height-(yoffset*2)-2);
+		else
+			clearlooks_rounded_rectangle (cr, xoffset+1, yoffset+1, width-(xoffset*2)-2, height-(yoffset*2)-2, widget->roundness-1,
+			                              widget->corners & (MRN_CORNER_TOPLEFT | MRN_CORNER_TOPRIGHT | MRN_CORNER_BOTTOMLEFT));
+
+		cairo_clip (cr);
+
+		cairo_rectangle (cr, xoffset+1, yoffset+1, width-(xoffset*2)-2, 3);
+		pattern = cairo_pattern_create_linear (xoffset+1, yoffset+1, xoffset+1, yoffset+4);
+		cairo_pattern_add_color_stop_rgba (pattern, 0.0, shadow.r, shadow.g, shadow.b, 0.58);
+		cairo_pattern_add_color_stop_rgba (pattern, 1.0, shadow.r, shadow.g, shadow.b, 0.0);
+		cairo_set_source (cr, pattern);
+		cairo_fill (cr);
+		cairo_pattern_destroy (pattern);
+
+		cairo_rectangle (cr, xoffset+1, yoffset+1, 3, height-(yoffset*2)-2);
+		pattern = cairo_pattern_create_linear (xoffset+1, yoffset+1, xoffset+4, yoffset+1);
+		cairo_pattern_add_color_stop_rgba (pattern, 0.0, shadow.r, shadow.g, shadow.b, 0.58);
+		cairo_pattern_add_color_stop_rgba (pattern, 1.0, shadow.r, shadow.g, shadow.b, 0.0);
+		cairo_set_source (cr, pattern);
+		cairo_fill (cr);
+		cairo_pattern_destroy (pattern);
+
+		cairo_restore (cr);
+
+		murrine_draw_inset (cr, &widget->parentbg, xoffset-0.5, yoffset-0.5, width-(xoffset*2)+1, height-(yoffset*2)+1, widget->roundness+1, widget->corners);
+	}
+
+	/* Draw the border */
+	murrine_set_color_rgb (cr, widget->disabled ? &border_disabled : &border_normal);
+	murrine_rounded_rectangle (cr, xoffset+0.5, yoffset+0.5, width-(xoffset*2)-1, height-(yoffset*2)-1, widget->roundness, widget->corners);
+	cairo_stroke (cr);
+}
+
+static void
+murrine_rgba_draw_entry (cairo_t *cr,
+                         const MurrineColors    *colors,
+                         const WidgetParameters *widget,
+                         int x, int y, int width, int height)
+{
+	const MurrineRGB *base = &colors->base[widget->state_type];
+	MurrineRGB border = colors->shade[widget->disabled ? 4 : 5];
+	int xoffset, yoffset = 0;
+	int radius = CLAMP (widget->roundness, 0, 3);
+
+	if (widget->xthickness > 1)
+		xoffset = 1;
+	if (widget->ythickness > 1)
+		yoffset = 1;
+
+	murrine_shade (&border, &border, 0.92);
+
+	cairo_translate (cr, x+0.5, y+0.5);
+	cairo_set_line_width (cr, 1.0);
+
+	/* Draw (erase) the background */
+	/* // CLEARING should be useless... testing
+	cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR);
+	cairo_paint (cr);
+	*/
+	cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+
+	/* Fill the background (shouldn't have to) */
+	cairo_rectangle (cr, -0.5, -0.5, width, height);
+	murrine_set_color_rgba (cr, &widget->parentbg, WINDOW_OPACITY);
+	cairo_fill (cr);
+
+	/* Fill the entry's base color (why isn't is large enough by default?) */
+	cairo_rectangle (cr, 1.5, 1.5, width-3, height-3);
+	murrine_set_color_rgba (cr, base, ENTRY_OPACITY);
+	cairo_fill (cr);
+
+	cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
+
+	murrine_draw_inset (cr, &widget->parentbg, 0, 0, width-1, height-1, radius+1, widget->corners);
+
+	/* Draw the focused border */
+	if (widget->focus)
+	{
+		cairo_rectangle (cr, 2, 2, width-5, height-5);
+		murrine_set_color_rgba (cr, &colors->spot[1], 0.6);
+		cairo_stroke(cr);
+	}
+	else
+	{
+		MurrineRGB highlight;
+		murrine_shade (base, &highlight, 1.15);
+
+		cairo_move_to (cr, 2, height-3);
+		cairo_line_to (cr, 2, 2);
+		cairo_line_to (cr, width-3, 2);
+
+		murrine_set_color_rgba (cr, &highlight, widget->disabled ? 0.3 : 0.6);
+		cairo_stroke (cr);
+	}
+
+	/* Draw the border */
+	if (widget->focus)
+		murrine_set_color_rgb (cr, &colors->spot[2]);
+	else
+		murrine_set_color_rgb (cr, &border);
+
+	murrine_rounded_rectangle (cr, 1, 1, width-3, height-3, radius, widget->corners);
+	cairo_stroke (cr);
+}
+
+static void
+murrine_scale_draw_gradient (cairo_t *cr,
+                             const MurrineRGB *c1,
+                             const MurrineRGB *c2,
+                             int x, int y, int width, int height,
+                             boolean alpha)
+{
+	if (alpha)
+		murrine_set_color_rgba (cr, c1, 0.4);
+	else
+		murrine_set_color_rgb (cr, c1);
+
+	cairo_rectangle (cr, x, y, width, height);
+	cairo_fill (cr);
+
+	cairo_rectangle (cr, x, y, width, height);
+	murrine_set_color_rgba (cr, c2, 0.82);
+	cairo_stroke (cr);
+}
+
+static void
+murrine_rgba_draw_scale_trough (cairo_t *cr,
+                                const MurrineColors    *colors,
+                                const WidgetParameters *widget,
+                                const SliderParameters *slider,
+                                int x, int y, int width, int height)
+{
+	int     fill_x, fill_y, fill_width, fill_height; /* Fill x,y,w,h */
+	int     trough_width, trough_height;
+	double  translate_x, translate_y;
+	int     fill_size = slider->fill_size;
+	int     TROUGH_SIZE = 6;
+
+	if (slider->horizontal)
+	{
+		if (fill_size > width-3)
+			fill_size = width-3;
+
+		fill_x        = slider->inverted ? width - fill_size - 3 : 0;
+		fill_y        = 0;
+		fill_width    = fill_size;
+		fill_height   = TROUGH_SIZE-2;
+
+		trough_width  = width-3;
+		trough_height = TROUGH_SIZE-2;
+
+		translate_x   = x + 0.5;
+		translate_y   = y + 0.5 + (height/2) - (TROUGH_SIZE/2);
+	}
+	else
+	{
+		if (fill_size > height-3)
+			fill_size = height-3;
+
+		fill_x        = 0;
+		fill_y        = slider->inverted ? height - fill_size - 3 : 0;
+		fill_width    = TROUGH_SIZE-2;
+		fill_height   = fill_size;
+
+		trough_width  = TROUGH_SIZE-2;
+		trough_height = height-3;
+
+		translate_x   = x + 0.5 + (width/2) - (TROUGH_SIZE/2);
+		translate_y   = y + 0.5;
+	}
+
+	cairo_set_line_width (cr, 1.0);
+	cairo_translate (cr, translate_x, translate_y);
+
+	murrine_draw_inset (cr, &widget->parentbg, 0, 0, trough_width+2, trough_height+2, 0, 0);
+
+	cairo_translate (cr, 1, 1);
+
+	murrine_scale_draw_gradient (cr, &colors->shade[1],
+	                             &colors->shade[5], /* border */
+	                             0, 0, trough_width, trough_height,
+	                             TRUE);
+
+	murrine_scale_draw_gradient (cr, &colors->spot[1],
+	                             &colors->spot[2], /* border */
+	                             fill_x, fill_y, fill_width, fill_height,
+	                             FALSE);
+}
+
+static void
+murrine_rgba_draw_progressbar_trough (cairo_t *cr,
+                                      const MurrineColors    *colors,
+                                      const WidgetParameters *widget,
+                                      int x, int y, int width, int height)
+{
+	const MurrineRGB *border = &colors->shade[4];
+
+	cairo_set_line_width (cr, 1.0);
+	cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+
+	/* Fill with bg color */
+	cairo_rectangle (cr, x, y, width, height);
+	murrine_set_color_rgba (cr, &colors->bg[widget->state_type], 0.8);
+	cairo_fill (cr);
+
+	cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
+
+	/* Create trough box */
+	cairo_rectangle (cr, x+1, y+1, width-2, height-2);
+	murrine_set_color_rgba (cr, &colors->shade[1], 0.8);
+	cairo_fill (cr);
+
+	/* Draw border */
+	cairo_rectangle (cr, x+0.5, y+0.5, width-1, height-1);
+	murrine_set_color_rgba (cr, border, 0.8);
+	cairo_stroke (cr);
+}
+
+static void
+murrine_rgba_draw_progressbar_fill (cairo_t *cr,
+                                    const MurrineColors         *colors,
+                                    const WidgetParameters      *widget,
+                                    const ProgressBarParameters *progressbar,
+                                    int x, int y, int width, int height,
+                                    gint offset)
+{
+	boolean    is_horizontal = progressbar->orientation < 2;
+	double     tile_pos = 0;
+	double     stroke_width;
+	int        x_step;
+	const      MurrineRGB *fill = &colors->spot[1];
+	const      MurrineRGB *border = &colors->spot[2];
+	MurrineRGB highlight;
+
+	murrine_shade (fill, &highlight, widget->highlight_ratio);
+
+	cairo_rectangle (cr, x, y, width, height);
+
+	if (is_horizontal)
+	{
+		if (progressbar->orientation == MRN_ORIENTATION_LEFT_TO_RIGHT)
+			rotate_mirror_translate (cr, 0, x, y, FALSE, FALSE);
+		else
+			rotate_mirror_translate (cr, 0, x+width, y, TRUE, FALSE);
+	}
+	else
+	{
+		int tmp = height; height  = width; width   = tmp;
+
+		x = x + 1;
+		y = y - 1;
+		width = width + 2;
+		height = height - 2;
+
+		if (progressbar->orientation == MRN_ORIENTATION_TOP_TO_BOTTOM)
+			rotate_mirror_translate (cr, M_PI/2, x, y, FALSE, FALSE);
+		else
+			rotate_mirror_translate (cr, M_PI/2, x, y+width, TRUE, FALSE);
+	}
+
+	cairo_save (cr);
+	cairo_clip (cr);
+
+	stroke_width = height*2;
+	x_step = (((float)stroke_width/10)*offset);
+	cairo_set_line_width (cr, 1.0);
+
+	cairo_save (cr);
+	cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+
+	cairo_rectangle (cr, 1.5, 0.5, width-2, height-1);
+
+	/* Draw fill */
+	murrine_set_gradient (cr, fill, widget->mrn_gradient, 1.5, 0.5, 0, height-1, widget->mrn_gradient.gradients, FALSE);
+
+	/* Draw the glass effect */
+	if (widget->glazestyle > 0)
+	{
+		widget->glazestyle == 2 ? cairo_fill_preserve (cr) : cairo_fill (cr);
+		if (widget->glazestyle < 3)
+			murrine_draw_curved_highlight (cr, 1, width, height);
+		else
+			murrine_draw_curved_highlight_top (cr, 1, width, height);
+	}
+	else
+	{
+		cairo_fill (cr);
+		murrine_draw_flat_highlight (cr, 1.5, 0.5, width-2, height);
+	}
+
+	murrine_set_gradient (cr, &highlight, widget->mrn_gradient, 1.5, 0.5, 0, height-1, widget->mrn_gradient.gradients, TRUE);
+	cairo_fill (cr);
+
+	if (widget->glazestyle == 4)
+	{
+		murrine_draw_curved_highlight_bottom (cr, 1, width, height+1);
+		MurrineRGB shadow;
+		murrine_shade (fill, &shadow, 1.0/widget->highlight_ratio);
+		murrine_set_gradient (cr, &shadow, widget->mrn_gradient, 1.5, 0.5, 0, height-1, widget->mrn_gradient.gradients, TRUE);
+		cairo_fill (cr);
+	}
+
+	cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
+
+	murrine_shade (fill, &highlight, widget->highlight_ratio*widget->innerborder_ratio);
+	murrine_draw_innerborder (cr, &highlight, fill, widget->mrn_gradient,
+	                          2.5, 1.5,
+	                          width-5, height-3,
+	                          widget->mrn_gradient.gradients, TRUE,
+	                          widget->glazestyle, 0, MRN_CORNER_NONE);
+
+	/* Draw strokes */
+	while (tile_pos <= width+x_step-2)
+	{
+		cairo_move_to (cr, stroke_width/2-x_step, 0);
+		cairo_line_to (cr, stroke_width-x_step,   0);
+		cairo_line_to (cr, stroke_width/2-x_step, height);
+		cairo_line_to (cr, -x_step, height);
+
+		cairo_translate (cr, stroke_width, 0);
+		tile_pos += stroke_width;
+	}
+
+	murrine_set_color_rgba (cr, border, 0.15);
+	cairo_fill (cr);
+	cairo_restore (cr);
+
+	/* Draw the border */
+	murrine_set_color_rgba (cr, border, 0.8);
+	cairo_rectangle (cr, 1.5, 0.5, width-3, height-1);
+	cairo_stroke (cr);
+}
+
+static void
+murrine_rgba_draw_menubar (cairo_t *cr,
+                           const MurrineColors *colors,
+                           const WidgetParameters *widget,
+                           int x, int y, int width, int height,
+                           int menubarstyle)
+{
+	const MurrineRGB *fill = &colors->bg[0];
+
+	cairo_translate (cr, x, y);
+	cairo_rectangle (cr, 0, 0, width, height);
+
+	cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+
+	/* Glass menubar */
+	if (menubarstyle == 1)
+	{
+		/* XXX: should use another gradient rgba_opacity */
+		MurrineRGB highlight;
+		murrine_set_gradient (cr, fill, widget->mrn_gradient, 0, 0, 0, height, widget->mrn_gradient.gradients, FALSE);
+		murrine_shade (fill, &highlight, widget->highlight_ratio);
+
+		if (widget->glazestyle > 0)
+		{
+			widget->glazestyle == 2 ? cairo_fill_preserve (cr) : cairo_fill (cr);
+			if (widget->glazestyle < 3)
+				murrine_draw_curved_highlight (cr, 0, width, height);
+			else
+				murrine_draw_curved_highlight_top (cr, 0, width, height);
+		}
+		else
+		{
+			cairo_fill (cr);
+			murrine_draw_flat_highlight (cr, 0, 0, width, height);
+		}
+
+		murrine_set_gradient (cr, &highlight, widget->mrn_gradient, 0, 0, 0, height, widget->mrn_gradient.gradients, TRUE);
+		cairo_fill (cr);
+
+		if (widget->glazestyle == 4)
+		{
+			murrine_draw_curved_highlight_bottom (cr, 0, width, height);
+			MurrineRGB shadow;
+			murrine_shade (fill, &shadow, 1.0/widget->highlight_ratio);
+			murrine_set_color_rgb (cr, &shadow);
+			cairo_fill (cr);
+		}
+
+		cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
+
+		if (widget->glazestyle == 2)
+		{
+			murrine_draw_innerborder (cr, &highlight, fill, widget->mrn_gradient,
+			                          1.5, 1.5,
+			                          width-3, height-3,
+			                          widget->mrn_gradient.gradients, TRUE,
+			                          widget->glazestyle, widget->roundness, widget->corners);
+		}
+	}
+	else if (menubarstyle == 2) /* Gradient menubar */
+	{
+		cairo_pattern_t *pattern;
+		MurrineRGB lower;
+		murrine_shade (fill, &lower, 0.95);
+		pattern = cairo_pattern_create_linear (0, 0, 0, height);
+		cairo_pattern_add_color_stop_rgba (pattern, 0.0, fill->r, fill->g, fill->b, MENUBAR_OPACITY);
+		cairo_pattern_add_color_stop_rgba (pattern, 1.0, lower.r, lower.g, lower.b, MENUBAR_OPACITY);
+		cairo_set_source (cr, pattern);
+		cairo_fill (cr);
+		cairo_pattern_destroy (pattern);
+
+		cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
+	}
+	else if (menubarstyle == 3) /* Striped menubar */
+	{
+		cairo_pattern_t *pattern;
+		MurrineRGB low, top;
+		murrine_shade (fill, &top, 0.9);
+		murrine_shade (fill, &low, 1.1);
+		pattern = cairo_pattern_create_linear (0, 0, 0, height);
+		cairo_pattern_add_color_stop_rgba (pattern, 0.0, top.r, top.g, top.b, MENUBAR_STRIPED_OPACITY);
+		cairo_pattern_add_color_stop_rgba (pattern, 1.0, low.r, low.g, low.b, MENUBAR_STRIPED_OPACITY);
+		cairo_set_source (cr, pattern);
+		cairo_fill (cr);
+
+		cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
+
+		cairo_pattern_destroy (pattern);
+		int counter = -height;
+		cairo_set_line_width  (cr, 1.0);
+		murrine_shade (&low, &low, 0.9);
+		murrine_set_color_rgba (cr, &low, MENUBAR_STRIPED_OPACITY);
+		while (counter < width)
+		{
+			cairo_move_to (cr, counter, height);
+			cairo_line_to (cr, counter+height, 0);
+			cairo_stroke  (cr);
+			counter += 5;
+		}
+	}
+	else /* Flat menubar */
+	{
+		murrine_set_color_rgba (cr, fill, MENUBAR_OPACITY);
+		cairo_fill (cr);
+
+		cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
+	}
+
+	/* Draw bottom line */
+	if (menubarstyle == 1 && widget->glazestyle == 2)
+		cairo_rectangle (cr, 0.5, 0.5, width-1, height-1);
+#ifndef HAVE_MACMENU
+	else
+	{
+		cairo_set_line_width (cr, 1.0);
+		cairo_move_to        (cr, 0, height-0.5);
+		cairo_line_to        (cr, width, height-0.5);
+	}
+
+	murrine_set_color_rgb (cr, &colors->shade[4]);
+	cairo_stroke          (cr);
+#endif
+}
+
+static void
+murrine_rgba_draw_toolbar (cairo_t *cr,
+                           const MurrineColors    *colors,
+                           const WidgetParameters *widget,
+                           const ToolbarParameters *toolbar,
+                           int x, int y, int width, int height)
+{
+	const MurrineRGB *dark = &colors->shade[4];
+	const MurrineRGB *fill = &colors->bg[0];
+	const MurrineRGB *top  = &colors->shade[0];
+
+	cairo_translate (cr, x, y);
+	cairo_rectangle (cr, 0, 0, width, height);
+
+	cairo_set_line_width (cr, 1.0);
+	cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+
+#ifdef HAVE_MACMENU
+	murrine_set_color_rgba (cr, fill, WINDOW_OPACITY);
+	cairo_fill (cr);
+	cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
+#else
+	/* Glass toolbar */
+	if (toolbar->style == 1)
+	{
+		/* XXX: should use another gradient rgba_opacity */
+		MurrineRGB highlight;
+		murrine_set_gradient (cr, fill, widget->mrn_gradient, 0, 0, 0, height, widget->mrn_gradient.gradients, FALSE);
+		murrine_shade (fill, &highlight, widget->highlight_ratio);
+
+		/* Glass effect */
+		if (widget->glazestyle > 0)
+		{
+			widget->glazestyle == 2 ? cairo_fill_preserve (cr) : cairo_fill (cr);
+			if (widget->glazestyle < 3)
+				murrine_draw_curved_highlight (cr, 0, width, height);
+			else
+				murrine_draw_curved_highlight_top (cr, 0, width, height);
+		}
+		else
+		{
+			cairo_fill (cr);
+			murrine_draw_flat_highlight (cr, 0, 0, width, height);
+		}
+
+		murrine_set_gradient (cr, &highlight, widget->mrn_gradient, 0, 0, 0, height, widget->mrn_gradient.gradients, TRUE);
+		cairo_fill (cr);
+
+		if (widget->glazestyle == 4)
+		{
+			murrine_draw_curved_highlight_bottom (cr, 0, width, height);
+			MurrineRGB shadow;
+			murrine_shade (fill, &shadow, 1.0/widget->highlight_ratio);
+			murrine_set_color_rgb (cr, &shadow);
+			cairo_fill (cr);
+		}
+
+		cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
+	}
+	else if (toolbar->style == 2)
+	{
+		cairo_pattern_t *pattern;
+		MurrineRGB lower;
+		murrine_shade (fill, &lower, 0.95);
+		pattern = cairo_pattern_create_linear (0, 0, 0, height);
+		cairo_pattern_add_color_stop_rgba (pattern, 0.0, fill->r, fill->g, fill->b, TOOLBAR_OPACITY);
+		cairo_pattern_add_color_stop_rgba (pattern, 1.0, lower.r, lower.g, lower.b, TOOLBAR_OPACITY);
+		cairo_set_source (cr, pattern);
+		cairo_fill (cr);
+		cairo_pattern_destroy (pattern);
+
+		cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
+	}
+	else /* Flat toolbar */
+	{
+		murrine_set_color_rgba (cr, fill, TOOLBAR_OPACITY);
+		cairo_fill (cr);
+
+		cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
+
+		/* Draw highlight */
+		if (!toolbar->topmost)
+		{
+			cairo_move_to          (cr, 0, 0.5);
+			cairo_line_to          (cr, width, 0.5);
+			murrine_set_color_rgba (cr, top, 0.5);
+			cairo_stroke           (cr);
+		}
+	}
+#endif
+
+	/* Draw shadow */
+	cairo_move_to         (cr, 0, height-0.5);
+	cairo_line_to         (cr, width, height-0.5);
+	murrine_set_color_rgb (cr, dark);
+	cairo_stroke          (cr);
+}
+
+static void
+murrine_get_frame_gap_clip (int x, int y, int width, int height,
+                            const FrameParameters *frame,
+                            MurrineRectangle      *bevel,
+                            MurrineRectangle      *border)
+{
+	if (frame->gap_side == MRN_GAP_TOP)
+	{
+		MURRINE_RECTANGLE_SET ((*bevel),  1.5 + frame->gap_x,  -0.5,
+		                       frame->gap_width - 3, 2.0);
+		MURRINE_RECTANGLE_SET ((*border), 0.5 + frame->gap_x,  -0.5,
+		                       frame->gap_width - 2, 2.0);
+	}
+	else if (frame->gap_side == MRN_GAP_BOTTOM)
+	{
+		MURRINE_RECTANGLE_SET ((*bevel),  1.5 + frame->gap_x,  height - 2.5,
+		                       frame->gap_width - 3, 2.0);
+		MURRINE_RECTANGLE_SET ((*border), 0.5 + frame->gap_x,  height - 1.5,
+		                       frame->gap_width - 2, 2.0);
+	}
+	else if (frame->gap_side == MRN_GAP_LEFT)
+	{
+		MURRINE_RECTANGLE_SET ((*bevel),  -0.5, 1.5 + frame->gap_x,
+		                       2.0, frame->gap_width - 3);
+		MURRINE_RECTANGLE_SET ((*border), -0.5, 0.5 + frame->gap_x,
+		                       1.0, frame->gap_width - 2);
+	}
+	else if (frame->gap_side == MRN_GAP_RIGHT)
+	{
+		MURRINE_RECTANGLE_SET ((*bevel),  width - 2.5, 1.5 + frame->gap_x,
+		                       2.0, frame->gap_width - 3);
+		MURRINE_RECTANGLE_SET ((*border), width - 1.5, 0.5 + frame->gap_x,
+		                       1.0, frame->gap_width - 2);
+	}
+}
+
+static void
+murrine_rgba_draw_frame (cairo_t *cr,
+                         const MurrineColors    *colors,
+                         const WidgetParameters *widget,
+                         const FrameParameters  *frame,
+                         int x, int y, int width, int height)
+{
+	MurrineRGB *border = frame->border;
+	MurrineRectangle bevel_clip;
+	MurrineRectangle frame_clip;
+
+	const MurrineRGB *dark = &colors->shade[5];
+
+	MurrineRGB highlight, shadow_color;
+
+	murrine_shade (&colors->bg[0], &highlight, 1.15);
+	murrine_shade (&colors->bg[0], &shadow_color, 0.4);
+
+	if (frame->shadow == MRN_SHADOW_NONE)
+		return;
+
+	if (frame->gap_x != -1)
+		murrine_get_frame_gap_clip (x, y, width, height,
+		                            frame, &bevel_clip, &frame_clip);
+
+	cairo_set_line_width (cr, 1.0);
+	cairo_translate      (cr, x+0.5, y+0.5);
+
+	/* save everything */
+	cairo_save (cr);
+
+	/* Set clip for the bevel */
+	if (frame->gap_x != -1)
+	{
+		/* Set clip for gap */
+		cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD);
+		cairo_rectangle     (cr, -0.5, -0.5, width, height);
+		cairo_rectangle     (cr, bevel_clip.x, bevel_clip.y, bevel_clip.width, bevel_clip.height);
+		cairo_clip          (cr);
+	}
+
+	/* Draw the bevel */
+	if (frame->shadow == MRN_SHADOW_ETCHED_IN || frame->shadow == MRN_SHADOW_ETCHED_OUT)
+	{
+		if (frame->shadow == MRN_SHADOW_ETCHED_IN)
+			murrine_rounded_rectangle (cr, 1, 1, width-2, height-2, widget->roundness, widget->corners);
+		else
+			murrine_rounded_rectangle (cr, 0, 0, width-2, height-2, widget->roundness, widget->corners);
+		murrine_set_color_rgba (cr, &highlight, 0.5);
+		cairo_stroke (cr);
+	}
+	else if (frame->shadow != MRN_SHADOW_NONE && frame->shadow != MRN_SHADOW_FLAT)
+	{
+		ShadowParameters shadow;
+		shadow.corners = widget->corners;
+		shadow.shadow  = frame->shadow;
+		cairo_move_to (cr, 1, height-2);
+		cairo_line_to (cr, 1, 1);
+		cairo_line_to (cr, width-1.5, 1);
+		if (frame->shadow & MRN_SHADOW_OUT)
+			murrine_set_color_rgba (cr, &highlight, 0.5);
+		else
+			murrine_set_color_rgba (cr, &shadow_color, 0.13);
+		cairo_stroke (cr);
+		cairo_move_to (cr, width-2, 1.5);
+		cairo_line_to (cr, width-2, height-2);
+		cairo_line_to (cr, 0, height-2);
+		if (frame->shadow & MRN_SHADOW_OUT)
+			murrine_set_color_rgba (cr, &shadow_color, 0.13);
+		else
+			murrine_set_color_rgba (cr, &highlight, 0.5);
+		cairo_stroke (cr);
+	}
+
+	/* restore the previous clip region */
+	cairo_restore (cr);
+	cairo_save    (cr);
+	if (frame->gap_x != -1)
+	{
+		/* Set clip for gap */
+		cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD);
+		cairo_rectangle     (cr, -0.5, -0.5, width, height);
+		cairo_rectangle     (cr, frame_clip.x, frame_clip.y, frame_clip.width, frame_clip.height);
+		cairo_clip          (cr);
+	}
+
+	/* Draw frame */
+	if (frame->shadow == MRN_SHADOW_ETCHED_IN || frame->shadow == MRN_SHADOW_ETCHED_OUT)
+	{
+		murrine_set_color_rgb (cr, dark);
+		if (frame->shadow == MRN_SHADOW_ETCHED_IN)
+			murrine_rounded_rectangle (cr, 0, 0, width-2, height-2, widget->roundness, widget->corners);
+		else
+			murrine_rounded_rectangle (cr, 1, 1, width-2, height-2, widget->roundness, widget->corners);
+	}
+	else
+	{
+		murrine_set_color_rgb (cr, border);
+		murrine_rounded_rectangle (cr, 0, 0, width-1, height-1, widget->roundness, widget->corners);
+	}
+	cairo_stroke  (cr);
+	cairo_restore (cr);
+}
+
+static void
+murrine_rgba_draw_separator (cairo_t *cr,
+                             const MurrineColors       *colors,
+                             const WidgetParameters    *widget,
+                             const SeparatorParameters *separator,
+                             int x, int y, int width, int height)
+{
+	const MurrineRGB *dark      = &colors->shade[4];
+	const MurrineRGB *highlight = &colors->shade[0];
+
+	if (separator->horizontal)
+	{
+		cairo_set_line_width  (cr, 1.0);
+		cairo_translate       (cr, x, y+0.5);
+
+		cairo_move_to         (cr, 0.0,     0.0);
+		cairo_line_to         (cr, width+1, 0.0);
+		murrine_set_color_rgb (cr, dark);
+		cairo_stroke          (cr);
+
+#ifndef HAVE_MACMENU
+		cairo_move_to          (cr, 0.0,   1.0);
+		cairo_line_to          (cr, width, 1.0);
+		murrine_set_color_rgba (cr, highlight, 0.5);
+		cairo_stroke           (cr);
+#endif
+	}
+	else
+	{
+		cairo_set_line_width  (cr, 1.0);
+		cairo_translate       (cr, x+0.5, y);
+
+		cairo_move_to         (cr, 0.0, 0.0);
+		cairo_line_to         (cr, 0.0, height);
+		murrine_set_color_rgb (cr, dark);
+		cairo_stroke          (cr);
+
+#ifndef HAVE_MACMENU
+		cairo_move_to          (cr, 1.0, 0.0);
+		cairo_line_to          (cr, 1.0, height);
+		murrine_set_color_rgba (cr, highlight, 0.5);
+		cairo_stroke           (cr);
+#endif
+	}
+}
+
+static void
+murrine_rgba_draw_tab (cairo_t *cr,
+                       const MurrineColors    *colors,
+                       const WidgetParameters *widget,
+                       const TabParameters    *tab,
+                       int x, int y, int width, int height)
+{
+	const float      RADIUS = 3.0;
+	int              corners;
+	double           strip_size;
+	const MurrineRGB *stripe_fill = &colors->spot[1];
+	const MurrineRGB *stripe_border = &colors->spot[2];
+	const MurrineRGB *fill;
+	MurrineRGB       *border;
+	cairo_pattern_t* pattern;
+
+	fill = &colors->bg[widget->state_type];
+
+	if (!widget->active)
+		border = (MurrineRGB*)&colors->shade[5];
+	else
+		border = (MurrineRGB*)&colors->shade[4];
+
+	/* Set clip */
+	cairo_rectangle (cr, x, y, width, height);
+	cairo_clip      (cr);
+	cairo_new_path  (cr);
+
+	/* Translate and set line width */
+	cairo_set_line_width (cr, 1.0);
+	cairo_translate      (cr, x+0.5, y+0.5);
+
+	/* Make the tabs slightly bigger than they should be, to create a gap */
+	/* And calculate the strip size too, while you're at it */
+	if (tab->gap_side == MRN_GAP_TOP || tab->gap_side == MRN_GAP_BOTTOM)
+	{
+		height += RADIUS;
+		strip_size = (tab->gap_side == MRN_GAP_TOP ? 2.0/height : 2.0/(height-2));
+
+		if (tab->gap_side == MRN_GAP_TOP)
+		{
+			cairo_translate (cr, 0.0, -3.0); /* gap at the other side */
+			corners = MRN_CORNER_BOTTOMLEFT | MRN_CORNER_BOTTOMRIGHT;
+		}
+		else
+			corners = MRN_CORNER_TOPLEFT | MRN_CORNER_TOPRIGHT;
+	}
+	else
+	{
+		width += RADIUS;
+		strip_size = (tab->gap_side == MRN_GAP_LEFT ? 2.0/width : 2.0/(width-2));
+
+		if (tab->gap_side == MRN_GAP_LEFT)
+		{
+			cairo_translate (cr, -3.0, 0.0); /* gap at the other side */
+			corners = MRN_CORNER_TOPRIGHT | MRN_CORNER_BOTTOMRIGHT;
+		}
+		else
+			corners = MRN_CORNER_TOPLEFT | MRN_CORNER_BOTTOMLEFT;
+	}
+
+/*	murrine_set_color_rgba (cr, &colors->bg[0], 0.0); */
+/*	/* Draw (erase) the background */
+/*	cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+	cairo_paint (cr); */
+
+	/* Set tab shape */
+	if (widget->roundness < 2)
+		cairo_rectangle (cr, 0, 0, width-1, height-1);
+	else
+		clearlooks_rounded_rectangle (cr, 0, 0, width-1, height-1, widget->roundness, corners);
+
+	/* Draw fill */
+	if (!widget->active)
+	{
+		murrine_set_color_rgba (cr, fill, NOTEBOOK_OPACITY);
+		cairo_fill (cr);
+	}
+
+	/* Draw highlight */
+/*	if (!widget->active)
+	{
+		ShadowParameters shadow;
+
+		shadow.shadow  = MRN_SHADOW_OUT;
+		shadow.corners = widget->corners;
+
+		murrine_draw_highlight_and_shade (cr, colors, &shadow,
+		                                  width,
+		                                  height, widget->roundness-1);
+	}
+*/
+	if (widget->active)
+	{
+		MurrineRGB shade1, shade2, shade3, shade4;
+
+		MurrineGradients mrn_gradient_custom = widget->mrn_gradient;
+		mrn_gradient_custom.gradient_stop_1 = get_decreased_ratio (widget->mrn_gradient.gradient_stop_1, 3.0);
+		mrn_gradient_custom.gradient_stop_2 = get_decreased_ratio (widget->mrn_gradient.gradient_stop_2, 3.0);
+		mrn_gradient_custom.gradient_stop_3 = get_decreased_ratio (widget->mrn_gradient.gradient_stop_3, 3.0);
+		mrn_gradient_custom.gradient_stop_4 = get_decreased_ratio (widget->mrn_gradient.gradient_stop_4, 3.0);
+
+		double custom_highlight_ratio = widget->highlight_ratio;
+		custom_highlight_ratio = get_decreased_ratio (widget->highlight_ratio, 2.0);
+
+		if (mrn_gradient_custom.gradients)
+		{
+			if (mrn_gradient_custom.has_gradient_stop)
+			{
+				murrine_shade (fill, &shade1, mrn_gradient_custom.gradient_stop_1*custom_highlight_ratio);
+				murrine_shade (fill, &shade2, mrn_gradient_custom.gradient_stop_2*custom_highlight_ratio);
+				murrine_shade (fill, &shade3, mrn_gradient_custom.gradient_stop_3);
+				murrine_shade (fill, &shade4, mrn_gradient_custom.gradient_stop_4);
+			}
+			else
+			{
+				murrine_shade (fill, &shade1, 1.1*custom_highlight_ratio);
+				murrine_shade (fill, &shade2, 1.0*custom_highlight_ratio);
+				murrine_shade (fill, &shade3, 1.0);
+				murrine_shade (fill, &shade4, 1.1);;
+			}
+		}
+		else
+		{
+			murrine_shade (fill, &shade1, 1.0*custom_highlight_ratio);
+			murrine_shade (fill, &shade2, 1.0*custom_highlight_ratio);
+			murrine_shade (fill, &shade3, 1.0);
+			murrine_shade (fill, &shade4, 1.0);
+		}
+
+		switch (tab->gap_side)
+		{
+			case MRN_GAP_TOP:
+				pattern = cairo_pattern_create_linear (0, height-2, 0, 0);
+				break;
+			case MRN_GAP_BOTTOM:
+				pattern = cairo_pattern_create_linear (0, 1, 0, height);
+				break;
+			case MRN_GAP_LEFT:
+				pattern = cairo_pattern_create_linear (width-2, 0, 1, 0);
+				break;
+			case MRN_GAP_RIGHT:
+				pattern = cairo_pattern_create_linear (1, 0, width-2, 0);
+				break;
+		}
+
+		if (widget->roundness < 2)
+			cairo_rectangle (cr, 0, 0, width-1, height-1);
+		else
+			clearlooks_rounded_rectangle (cr, 0, 0, width-1, height-1, widget->roundness, corners);
+
+		cairo_pattern_add_color_stop_rgba (pattern, 0.0, shade1.r, shade1.g, shade1.b, NOTEBOOK_OPACITY);
+		cairo_pattern_add_color_stop_rgba (pattern, 0.4, shade2.r, shade2.g, shade2.b, NOTEBOOK_OPACITY);
+		cairo_pattern_add_color_stop_rgba (pattern, 0.4, shade3.r, shade3.g, shade3.b, NOTEBOOK_OPACITY);
+		cairo_pattern_add_color_stop_rgba (pattern, 1.0, shade4.r, shade4.g, shade4.b, NOTEBOOK_OPACITY);
+		cairo_set_source (cr, pattern);
+		cairo_fill (cr);
+		cairo_pattern_destroy (pattern);
+
+		cairo_set_line_width (cr, 1.0);
+		murrine_set_color_rgba (cr, &colors->shade[0], 0.2);
+
+		if (widget->roundness < 2)
+			cairo_rectangle (cr, 1, 1, width-3, height-3);
+		else
+			clearlooks_rounded_rectangle (cr, 1, 1, width-3, height-3, widget->roundness, corners);
+
+		cairo_stroke (cr);
+	}
+	else
+	{
+		/* Draw shade */
+		switch (tab->gap_side)
+		{
+			case MRN_GAP_TOP:
+				pattern = cairo_pattern_create_linear (0, height-2, 0, 0);
+				break;
+			case MRN_GAP_BOTTOM:
+				pattern = cairo_pattern_create_linear (0, 0, 0, height);
+				break;
+			case MRN_GAP_LEFT:
+				pattern = cairo_pattern_create_linear (width-2, 0, 0, 0);
+				break;
+			case MRN_GAP_RIGHT:
+				pattern = cairo_pattern_create_linear (0, 0, width, 0);
+				break;
+		}
+
+		if (widget->roundness < 2)
+			cairo_rectangle (cr, 0, 0, width-1, height-1);
+		else
+			clearlooks_rounded_rectangle (cr, 0, 0, width-1, height-1, widget->roundness, corners);
+
+		cairo_pattern_add_color_stop_rgba (pattern, 0.0,        stripe_fill->r, stripe_fill->g, stripe_fill->b, NOTEBOOK_OPACITY);
+		cairo_pattern_add_color_stop_rgba (pattern, strip_size, stripe_fill->r, stripe_fill->g, stripe_fill->b, NOTEBOOK_OPACITY);
+		cairo_pattern_add_color_stop_rgba (pattern, strip_size, fill->r, fill->g, fill->b, 0.0);
+		cairo_set_source (cr, pattern);
+		cairo_fill (cr);
+		cairo_pattern_destroy (pattern);
+	}
+
+	murrine_rounded_rectangle (cr, 0, 0, width-1, height-1, widget->roundness, corners);
+
+	if (widget->active)
+	{
+		murrine_set_color_rgb  (cr, border);
+		cairo_stroke (cr);
+	}
+	else
+	{
+		switch (tab->gap_side)
+		{
+			case MRN_GAP_TOP:
+				pattern = cairo_pattern_create_linear (2, height-2, 2, 2);
+				break;
+			case MRN_GAP_BOTTOM:
+				pattern = cairo_pattern_create_linear (2, 2, 2, height);
+				break;
+			case MRN_GAP_LEFT:
+				pattern = cairo_pattern_create_linear (width-2, 2, 2, 2);
+				break;
+			case MRN_GAP_RIGHT:
+				pattern = cairo_pattern_create_linear (2, 2, width, 2);
+				break;
+		}
+
+		cairo_pattern_add_color_stop_rgb (pattern, 0.0,        stripe_border->r, stripe_border->g, stripe_border->b);
+		cairo_pattern_add_color_stop_rgb (pattern, strip_size, stripe_border->r, stripe_border->g, stripe_border->b);
+		cairo_pattern_add_color_stop_rgb (pattern, strip_size, stripe_border->r, stripe_border->g, stripe_border->b);
+		cairo_pattern_add_color_stop_rgb (pattern, 0.8,        border->r,        border->g,        border->b);
+		cairo_set_source (cr, pattern);
+		cairo_stroke (cr);
+		cairo_pattern_destroy (pattern);
+	}
+}
+
+static void
+murrine_rgba_draw_scrollbar_trough (cairo_t *cr,
+                                    const MurrineColors       *colors,
+                                    const WidgetParameters    *widget,
+                                    const ScrollBarParameters *scrollbar,
+                                    int x, int y, int width, int height)
+{
+	const MurrineRGB *bg     = &colors->shade[scrollbar->stepperstyle < 1 ? 1 : 0];
+	const MurrineRGB *border = &colors->shade[scrollbar->stepperstyle < 1 ? 4 : 5];
+
+	cairo_set_line_width (cr, 1.0);
+
+	if (scrollbar->horizontal)
+	{
+		int tmp = height;
+		rotate_mirror_translate (cr, M_PI/2, x, y, FALSE, FALSE);
+		height = width;
+		width = tmp;
+	}
+	else
+	{
+		cairo_translate (cr, x, y);
+	}
+
+	/* Draw fill */
+	clearlooks_rounded_rectangle (cr, 1, 0, width-2, height, widget->roundness, widget->corners);
+	murrine_set_color_rgba (cr, bg, 0.4);
+	cairo_fill (cr);
+
+	/* Draw border */
+	murrine_rounded_rectangle (cr, 0.5, 0.5, width-1, height-1, widget->roundness, widget->corners);
+	murrine_set_color_rgba (cr, border, 0.82);
+	cairo_stroke (cr);
+}
+
+void
+murrine_rgba_draw_scrollbar_stepper (cairo_t *cr,
+                                     const MurrineColors       *colors,
+                                     const WidgetParameters    *widget,
+                                     const ScrollBarParameters *scrollbar,
+                                     int x, int y, int width, int height)
+{
+	const MurrineRGB *fill  = &colors->bg[widget->state_type];
+	MurrineRGB border_normal;
+	MurrineRGB highlight;
+
+	murrine_shade (&colors->shade[7], &border_normal, 0.95);
+	murrine_shade (fill, &highlight, widget->highlight_ratio);
+
+	if (!scrollbar->horizontal)
+		murrine_exchange_axis (cr, &x, &y, &width, &height);
+
+	/* Border color */
+	murrine_mix_color (&border_normal, fill, 0.45, &border_normal);
+
+	cairo_translate (cr, x, y);
+	cairo_set_line_width (cr, 1.0);
+	cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+
+	/* Draw the bg */
+	if (widget->roundness < 2)
+		cairo_rectangle (cr, 1, 1, width-2, height-2);
+	else
+		clearlooks_rounded_rectangle (cr, 0.5, 0.5, width-1, height-1, widget->roundness+1, widget->corners);
+	murrine_set_gradient (cr, fill, widget->mrn_gradient, 1, 1, 0, height-2, widget->mrn_gradient.gradients, FALSE);
+
+	cairo_save (cr);
+
+	int curve_pos = 1;
+	if (widget->glazestyle != 4)
+		curve_pos = 2;
+
+	/* Draw the glass effect */
+	if (widget->glazestyle > 0)
+	{
+		cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD);
+		widget->glazestyle == 2 ? cairo_fill_preserve (cr) : cairo_fill (cr);
+		if (widget->glazestyle < 3)
+			murrine_draw_curved_highlight (cr, curve_pos, width, height);
+		else
+			murrine_draw_curved_highlight_top (cr, curve_pos, width, height);
+	}
+	else
+	{
+		cairo_fill (cr);
+		murrine_draw_flat_highlight (cr, 1, 1, width-2, height-2);
+	}
+
+	murrine_set_gradient (cr, &highlight, widget->mrn_gradient, 1, 1, 0, height-2, widget->mrn_gradient.gradients, TRUE);
+	cairo_fill (cr);
+
+	if (widget->glazestyle == 4)
+	{
+		murrine_draw_curved_highlight_bottom (cr, curve_pos, width, height);
+		MurrineRGB shadow;
+		murrine_shade (fill, &shadow, 1.0/widget->highlight_ratio);
+		murrine_set_gradient (cr, &shadow, widget->mrn_gradient, 1, 1, 0, height-2, widget->mrn_gradient.gradients, TRUE);
+		cairo_fill (cr);
+	}
+
+	cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
+
+	/* Draw the white inner border */
+	if (widget->glazestyle != 4)
+	{
+		murrine_shade (fill, &highlight, widget->innerborder_ratio*widget->highlight_ratio);
+		murrine_draw_innerborder (cr, &highlight, fill, widget->mrn_gradient,
+		                              1.5, 1.5,
+		                              width-3, height-3,
+		                              widget->mrn_gradient.gradients, TRUE,
+		                              widget->glazestyle, widget->roundness, widget->corners);
+	}
+
+	cairo_reset_clip (cr);
+	cairo_restore (cr);
+
+	murrine_set_color_rgb (cr, &border_normal);
+	/* Draw the border */
+	murrine_rounded_rectangle (cr, 0.5, 0.5, width-1, height-1, widget->roundness, widget->corners);
+	cairo_stroke (cr);
+}
+
+void
+murrine_rgba_draw_scrollbar_slider (cairo_t *cr,
+                                    const MurrineColors       *colors,
+                                    const WidgetParameters    *widget,
+                                    const ScrollBarParameters *scrollbar,
+                                    int x, int y, int width, int height)
+{
+	if (scrollbar->stepperstyle < 1)
+	{
+		if (scrollbar->junction & MRN_JUNCTION_BEGIN)
+		{
+			if (scrollbar->horizontal)
+			{
+				x -= 1;
+				width += 1;
+			}
+			else
+			{
+				y -= 1;
+				height += 1;
+			}
+		}
+		if (scrollbar->junction & MRN_JUNCTION_END)
+		{
+			if (scrollbar->horizontal)
+				width += 1;
+			else
+				height += 1;
+		}
+	}
+
+	/* Set colors */
+	MurrineRGB fill;
+	if (scrollbar->has_color)
+		fill = scrollbar->color;
+	else
+		fill = colors->bg[0];
+
+	MurrineRGB border;
+	murrine_shade (&colors->shade[7], &border, 0.95);
+	MurrineRGB highlight;
+
+	if (widget->prelight)
+		murrine_shade (&fill, &fill, 1.06);
+
+	murrine_shade (&fill, &highlight, widget->highlight_ratio);
+	/* Draw the border */
+	murrine_mix_color (&border, &fill, 0.5, &border);
+
+	if (scrollbar->horizontal)
+		cairo_translate (cr, x, y);
+
+	else
+	{
+		int tmp = height;
+		rotate_mirror_translate (cr, M_PI/2, x, y, FALSE, FALSE);
+		height = width;
+		width = tmp;
+	}
+
+	cairo_set_line_width (cr, 1.0);
+	cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+
+	murrine_rounded_rectangle_fast (cr, 0.5, 0.5, width-1, height-1, widget->corners);
+	murrine_set_color_rgb (cr, &border);
+	cairo_stroke (cr);
+
+	cairo_rectangle (cr, 1, 1, width-2, height-2);
+	murrine_set_gradient (cr, &fill, widget->mrn_gradient, 1, 1, 0, height-2, widget->mrn_gradient.gradients, FALSE);
+
+	/* Draw the glass effect */
+	if (widget->glazestyle > 0)
+	{
+		widget->glazestyle == 2 ? cairo_fill_preserve (cr) : cairo_fill (cr);
+		if (widget->glazestyle < 3)
+			murrine_draw_curved_highlight (cr, 1, width, height);
+		else
+			murrine_draw_curved_highlight_top (cr, 1, width, height);
+	}
+	else
+	{
+		cairo_fill (cr);
+		murrine_draw_flat_highlight (cr, 1, 1, width-2, height-2);
+	}
+
+	murrine_set_gradient (cr, &highlight, widget->mrn_gradient, 1, 1, 0, height-2, widget->mrn_gradient.gradients, TRUE);
+	cairo_fill (cr);
+
+	if (widget->glazestyle == 4)
+	{
+		murrine_draw_curved_highlight_bottom (cr, 1, width, height);
+		MurrineRGB shadow;
+		murrine_shade (&fill, &shadow, 1.0/widget->highlight_ratio);
+		murrine_set_color_rgb (cr, &shadow);
+		cairo_fill (cr);
+	}
+
+	cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
+
+	if (widget->glazestyle != 4)
+	{
+		murrine_shade (&fill, &highlight, widget->innerborder_ratio*widget->highlight_ratio);
+		murrine_draw_innerborder (cr, &highlight, &fill, widget->mrn_gradient,
+		                          1.5, 1.5,
+		                          width-3, height-3,
+		                          widget->mrn_gradient.gradients, TRUE,
+		                          widget->glazestyle, 0, MRN_CORNER_NONE);
+	}
+
+	/* Draw the options */
+	MurrineRGB style;
+	if (scrollbar->style > 0)
+		murrine_shade (&fill, &style, 0.55);
+
+	/* Draw the circles */
+	if (scrollbar->style == 1)
+	{
+		int circ_radius = 2;
+		int circ_space = 5;
+		int i;
+		int x1 = circ_space+circ_radius;
+		int y1 = height/2;
+		for (i = circ_space; i < width-circ_space; i += 2*circ_radius+circ_space)
+		{
+			cairo_move_to (cr, i, 1);
+			cairo_arc (cr, x1, y1, circ_radius, 0, M_PI*2);
+
+			x1 += 2*circ_radius+circ_space;
+
+			cairo_close_path (cr);
+			murrine_set_color_rgba (cr, &style, 0.15);
+			cairo_fill (cr);
+		}
+	}
+	if (scrollbar->style > 2)
+	{
+		/* Draw the diagonal strokes */
+		if (scrollbar->style < 5)
+		{
+			cairo_save (cr);
+			cairo_rectangle (cr, 1, 1, width-2, height-2);
+			cairo_clip (cr);
+			cairo_new_path (cr);
+			int counter = -width;
+			cairo_set_line_width (cr, 5); /* stroke width */
+			murrine_set_color_rgba (cr, &style, 0.08);
+			while (counter < height)
+			{
+				cairo_move_to (cr, width, counter);
+				cairo_line_to (cr, 0, counter+width);
+				cairo_stroke  (cr);
+				counter += 12;
+			}
+			cairo_restore (cr);
+		}
+		/* Draw the horizontal strokes */
+		if (scrollbar->style > 4)
+		{
+			int stroke_width = 7;
+			int stroke_space = 5;
+			int i;
+			murrine_set_color_rgba (cr, &style, 0.08);
+			for (i = stroke_space; i < width-stroke_space; i += stroke_width+stroke_space)
+			{
+				cairo_move_to (cr, i, 1);
+				cairo_rel_line_to (cr, 0, height-2);
+				cairo_rel_line_to (cr, stroke_width, 0);
+				cairo_rel_line_to (cr, 0, -(height-2));
+				cairo_fill (cr);
+			}
+		}
+	}
+	/* Draw the handle */
+	if (scrollbar->style > 0 && scrollbar->style % 2 == 0 )
+	{
+		int bar_x = width/2 - 4;
+		cairo_translate (cr, 0.5, 0.5);
+		int i;
+		for (i=0; i<3; i++)
+		{
+			cairo_move_to (cr, bar_x, 4.5);
+			cairo_line_to (cr, bar_x, height-5.5);
+			murrine_set_color_rgb (cr, &border);
+			cairo_stroke (cr);
+
+			bar_x += 3;
+		}
+	}
+}
+/*
+static void
+murrine_rgba_draw_tooltip (cairo_t *cr,
+                           const MurrineColors    *colors,
+                           const WidgetParameters *widget,
+                           int x, int y, int width, int height)
+{
+	MurrineRGB border, highlight;
+
+	MurrineGradients mrn_gradient_custom = widget->mrn_gradient;
+
+	mrn_gradient_custom.gradient_stop_1 = get_decreased_ratio (widget->mrn_gradient.gradient_stop_1, 2.0);
+	mrn_gradient_custom.gradient_stop_2 = get_decreased_ratio (widget->mrn_gradient.gradient_stop_2, 2.0);
+	mrn_gradient_custom.gradient_stop_3 = get_decreased_ratio (widget->mrn_gradient.gradient_stop_3, 2.0);
+	mrn_gradient_custom.gradient_stop_4 = get_decreased_ratio (widget->mrn_gradient.gradient_stop_4, 2.0);
+
+	murrine_shade (&colors->bg[widget->state_type], &border, 0.6);
+	murrine_shade (&colors->bg[widget->state_type], &highlight, 1.0);
+
+	cairo_save (cr);
+
+	cairo_translate (cr, x, y);
+	cairo_set_line_width (cr, 1.0);
+	cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR);
+	cairo_paint (cr);
+	cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
+
+	murrine_set_gradient (cr, &colors->bg[widget->state_type], mrn_gradient_custom, 0, 0, 0, height, widget->mrn_gradient.gradients, FALSE);
+	murrine_rounded_rectangle (cr, 0, 0, width, height, widget->roundness, MRN_CORNER_ALL);
+	cairo_fill (cr);
+
+	murrine_set_gradient (cr, &highlight, mrn_gradient_custom, 0, 0, 0, height, widget->mrn_gradient.gradients, TRUE);
+	murrine_rounded_rectangle (cr, 0, 0, width, height/2, widget->roundness, MRN_CORNER_TOPLEFT | MRN_CORNER_TOPRIGHT);
+	cairo_fill (cr);
+
+	murrine_set_color_rgb (cr, &border);
+	murrine_rounded_rectangle (cr, 0.5, 0.5, width-1, height-1, widget->roundness, MRN_CORNER_ALL);
+	cairo_stroke (cr);
+
+	cairo_restore (cr);
+}
+*/
+static void
+murrine_rgba_draw_handle (cairo_t *cr,
+                          const MurrineColors    *colors,
+                          const WidgetParameters *widget,
+                          const HandleParameters *handle,
+                          int x, int y, int width, int height)
+{
+	const MurrineRGB *dark  = &colors->shade[5];
+
+	int bar_height;
+	int bar_width  = 4;
+	int i, bar_y = 1;
+	int num_bars, bar_spacing;
+	num_bars    = 3;
+	bar_spacing = 3;
+	bar_height = num_bars * bar_spacing;
+
+	if (handle->horizontal)
+	{
+		int tmp = height;
+		rotate_mirror_translate (cr, M_PI/2, x + 0.5 + width/2 - bar_height/2, y + height/2 - bar_width/2, FALSE, FALSE);
+		height = width;
+		width = tmp;
+	}
+	else
+	{
+		cairo_translate (cr, x + width/2 - bar_width/2, y + height/2 - bar_height/2 + 0.5);
+	}
+
+	cairo_set_line_width (cr, 1.0);
+
+	for (i=0; i<num_bars; i++)
+	{
+		cairo_move_to (cr, 0, bar_y);
+		cairo_line_to (cr, bar_width, bar_y);
+		murrine_set_color_rgb (cr, dark);
+		cairo_stroke (cr);
+
+		bar_y += bar_spacing;
+	}
+}
+
+
+static void
+murrine_rgba_draw_radiobutton (cairo_t * cr,
+                               const MurrineColors    *colors,
+                               const WidgetParameters *widget,
+                               const OptionParameters *status,
+                               int x, int y, int width, int height,
+                               double trans)
+{
+	MurrineRGB border;
+	const MurrineRGB *dot;
+
+	width = height = 15;
+
+	if (widget->state_type == GTK_STATE_INSENSITIVE)
+	{
+		border = colors->shade[4];
+		dot    = &colors->shade[4];
+	}
+	else
+	{
+		border = colors->shade[6];
+		if (status->draw_bullet)
+			border = colors->spot[2];
+		dot    = &colors->text[widget->state_type];
+	}
+	murrine_mix_color (&border, widget->state_type != GTK_STATE_INSENSITIVE ?
+	                   status->draw_bullet ? &colors->spot[1] : &colors->bg[0] : &colors->bg[0], 0.2, &border);
+
+	cairo_translate (cr, x, y);
+
+	cairo_set_line_width (cr, 2);
+	cairo_arc (cr, 7, 7, 6, 0, M_PI*2);
+	murrine_set_color_rgba (cr, &colors->shade[8], 0.12);
+	cairo_stroke (cr);
+
+	cairo_set_line_width (cr, 1.0);
+
+	cairo_arc (cr, 7, 7, 5.5, 0, M_PI*2);
+
+	if (widget->state_type != GTK_STATE_INSENSITIVE)
+	{
+		const MurrineRGB *bg = &colors->base[0];
+		if (status->draw_bullet)
+			bg = &colors->spot[1];
+		if (widget->glazestyle != 2)
+		{
+			MurrineRGB highlight;
+			murrine_shade (bg, &highlight, widget->highlight_ratio);
+			murrine_set_gradient (cr, &highlight, widget->mrn_gradient, 0, 0, 0, 14, widget->mrn_gradient.gradients, FALSE);
+		}
+		else
+			murrine_set_gradient (cr, bg, widget->mrn_gradient, 0, 0, 0, 14, widget->mrn_gradient.gradients, FALSE);
+		cairo_fill_preserve (cr);
+	}
+
+	murrine_set_color_rgb (cr, &border);
+	cairo_stroke (cr);
+
+	cairo_arc (cr, 7, 7, 5, 0, M_PI*2);
+	cairo_clip (cr);
+
+	if (widget->state_type != GTK_STATE_INSENSITIVE)
+	{
+		const MurrineRGB *bg = &colors->base[0];
+		if (status->draw_bullet)
+			bg = &colors->spot[1];
+
+		cairo_rectangle (cr, 0, 7, width, height);
+		if (widget->glazestyle == 2)
+		{
+			MurrineRGB highlight;
+			murrine_shade (bg, &highlight, widget->highlight_ratio);
+			murrine_set_gradient (cr, &highlight, widget->mrn_gradient, 0, 0, 0, 14, widget->mrn_gradient.gradients, FALSE);
+		}
+		else
+			murrine_set_gradient (cr, bg, widget->mrn_gradient, 0, 0, 0, 14, widget->mrn_gradient.gradients, FALSE);
+		cairo_fill (cr);
+	}
+
+	/* inconsistent state is missing? */
+	if (status->draw_bullet)
+	{
+		cairo_arc (cr, 7, 7, 2, 0, M_PI*2);
+		/* murrine_set_color_rgb (cr, dot); */
+		murrine_set_color_rgba (cr, dot, trans);
+		cairo_fill (cr);
+	}
+
+	cairo_restore (cr);
+}
+
+static void
+murrine_rgba_draw_checkbox (cairo_t * cr,
+                            const MurrineColors    *colors,
+                            const WidgetParameters *widget,
+                            const OptionParameters *status,
+                            int x, int y, int width, int height,
+                            double trans)
+{
+	MurrineRGB border;
+	const MurrineRGB *dot;
+
+	width = height = 13;
+
+	if (widget->state_type == GTK_STATE_INSENSITIVE)
+	{
+		border = colors->shade[4];
+		dot    = &colors->shade[4];
+	}
+	else
+	{
+		border = colors->shade[6];
+		if (status->draw_bullet)
+			border = colors->spot[2];
+		dot    = &colors->text[widget->state_type];
+	}
+	murrine_mix_color (&border, widget->state_type != GTK_STATE_INSENSITIVE ?
+	                   status->draw_bullet ? &colors->spot[1] : &colors->bg[0] : &colors->bg[0], 0.24, &border);
+
+	cairo_translate (cr, x, y);
+	cairo_set_line_width (cr, 1.0);
+
+	if (widget->xthickness > 2 && widget->ythickness > 2)
+	{
+		cairo_rectangle (cr, 0.5, 0.5, width-1, height-1);
+		murrine_set_color_rgba (cr, &colors->shade[8], 0.12);
+		cairo_stroke (cr);
+
+		/* Draw the rectangle for the checkbox itself */
+		cairo_rectangle (cr, 1.5, 1.5, width-3, height-3);
+	}
+	else
+	{
+		cairo_rectangle (cr, 0.5, 0.5, width-1, height-1);
+	}
+
+
+	if (widget->state_type != GTK_STATE_INSENSITIVE)
+	{
+		const MurrineRGB *bg = &colors->base[0];
+		if (status->draw_bullet)
+			bg = &colors->spot[1];
+
+		if (widget->glazestyle == 2)
+		{
+			MurrineRGB highlight;
+			murrine_shade (bg, &highlight, widget->highlight_ratio);
+			murrine_set_gradient (cr, &highlight, widget->mrn_gradient, 0, 0, 0, 14, widget->mrn_gradient.gradients, FALSE);
+		}
+		else
+			murrine_set_gradient (cr, bg, widget->mrn_gradient, 0, 0, 0, 14, widget->mrn_gradient.gradients, FALSE);
+		cairo_fill_preserve (cr);
+	}
+
+	murrine_set_color_rgb (cr, &border);
+	cairo_stroke (cr);
+
+	if (widget->state_type != GTK_STATE_INSENSITIVE)
+	{
+		const MurrineRGB *bg = &colors->base[0];
+		if (status->draw_bullet)
+			bg = &colors->spot[1];
+
+		MurrineRGB highlight;
+		murrine_shade (bg, &highlight, widget->highlight_ratio);
+		if (widget->xthickness > 2 && widget->ythickness > 2)
+			cairo_rectangle (cr, 2, 2, width-4, (height-4)/2);
+		else
+			cairo_rectangle (cr, 1, 1, width-2, (height-2)/2);
+
+		if (widget->glazestyle != 2)
+		{
+			MurrineRGB highlight;
+			murrine_shade (bg, &highlight, widget->highlight_ratio);
+			murrine_set_gradient (cr, &highlight, widget->mrn_gradient, 0, 0, 0, 14, widget->mrn_gradient.gradients, FALSE);
+		}
+		else
+			murrine_set_gradient (cr, bg, widget->mrn_gradient, 0, 0, 0, 14, widget->mrn_gradient.gradients, FALSE);
+		cairo_fill (cr);
+	}
+
+	cairo_scale (cr, width / 13.0, height / 13.0);
+	if (status->draw_bullet)
+	{
+		if (status->inconsistent) /* Inconsistent */
+		{
+			cairo_set_line_width (cr, 2.0);
+			cairo_move_to (cr, 3, height*0.5);
+			cairo_line_to (cr, width-3, height*0.5);
+		}
+		else
+		{
+			cairo_translate (cr, -2, 0);
+		/*
+			if (widget && widget->parent && GTK_IS_MENU(widget->parent))
+				cairo_translate (cr, 0, 0);
+		*/
+			cairo_move_to (cr, 4, 8);
+			cairo_rel_line_to (cr, 5, 4);
+			cairo_rel_curve_to (cr, 1.4, -5, -1, -1, 5.7, -12.5);
+			cairo_rel_curve_to (cr, -4, 4, -4, 4, -6.7, 9.3);
+			cairo_rel_line_to (cr, -2.3, -2.5);
+		}
+
+		murrine_set_color_rgba (cr, dot, trans);
+		cairo_fill (cr);
+	}
+}
+
+static void
+murrine_rgba_draw_menu_frame (cairo_t *cr,
+                              const MurrineColors    *colors,
+                              const WidgetParameters *widget,
+                              int x, int y, int width, int height,
+                              int menustyle)
+{
+	const MurrineRGB *border = &colors->shade[5];
+	uint8 corners = (menustyle == 1 ? MRN_CORNER_TOPRIGHT | MRN_CORNER_BOTTOMRIGHT :
+	                                  MRN_CORNER_TOPRIGHT |
+	                                  MRN_CORNER_BOTTOMLEFT | MRN_CORNER_BOTTOMRIGHT);
+
+	cairo_translate      (cr, x, y);
+	cairo_set_line_width (cr, 1.0);
+	cairo_set_operator   (cr, CAIRO_OPERATOR_CLEAR);
+	cairo_paint (cr);
+	cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
+
+	clearlooks_rounded_rectangle (cr, 0.5, 0.5, width-1, height-1, widget->roundness, corners);
+	murrine_set_color_rgba (cr, &colors->bg[0], MENU_OPACITY);
+	cairo_fill (cr);
+
+	murrine_rounded_rectangle (cr, 0.5, 0.5, width-1, height-1, widget->roundness, corners);
+	murrine_set_color_rgb (cr, border);
+	cairo_stroke          (cr);
+
+	if (menustyle == 1)
+	{
+		MurrineRGB *fill = (MurrineRGB*)&colors->spot[1];
+		MurrineRGB border2;
+		murrine_shade (fill, &border2, 0.5);
+
+		cairo_rectangle (cr, 0.5, 0.5, 3, height-1);
+		murrine_set_color_rgb (cr, &border2);
+		cairo_stroke_preserve (cr);
+
+		murrine_set_color_rgb (cr, fill);
+		cairo_fill (cr);
+	}
+}
+
+static void
+murrine_rgba_draw_statusbar (cairo_t *cr,
+                             const MurrineColors    *colors,
+                             const WidgetParameters *widget,
+                             int x, int y, int width, int height)
+{
+	const MurrineRGB *dark = &colors->shade[4];
+	const MurrineRGB *highlight = &colors->shade[0];
+
+	cairo_set_line_width  (cr, 1);
+	cairo_translate       (cr, x, y+0.5);
+	cairo_move_to         (cr, 0, 0);
+	cairo_line_to         (cr, width, 0);
+	murrine_set_color_rgb (cr, dark);
+	cairo_stroke          (cr);
+
+	cairo_translate        (cr, 0, 1);
+	cairo_move_to          (cr, 0, 0);
+	cairo_line_to          (cr, width, 0);
+	murrine_set_color_rgba (cr, highlight, 0.5);
+	cairo_stroke           (cr);
+}
+
+void
+murrine_register_style_rgba (MurrineStyleFunctions *functions)
+{
+	functions->draw_button             = murrine_rgba_draw_button;
+	functions->draw_entry              = murrine_rgba_draw_entry;
+	functions->draw_scale_trough       = murrine_rgba_draw_scale_trough;
+	functions->draw_progressbar_trough = murrine_rgba_draw_progressbar_trough;
+	functions->draw_progressbar_fill   = murrine_rgba_draw_progressbar_fill;
+	functions->draw_menubar            = murrine_rgba_draw_menubar;
+	functions->draw_toolbar            = murrine_rgba_draw_toolbar;
+	functions->draw_frame              = murrine_rgba_draw_frame;
+	functions->draw_separator          = murrine_rgba_draw_separator;
+	functions->draw_tab                = murrine_rgba_draw_tab;
+	functions->draw_scrollbar_trough   = murrine_rgba_draw_scrollbar_trough;
+	functions->draw_scrollbar_stepper  = murrine_rgba_draw_scrollbar_stepper;
+	functions->draw_scrollbar_slider   = murrine_rgba_draw_scrollbar_slider;
+	functions->draw_handle             = murrine_rgba_draw_handle;
+	/* functions->draw_tooltip            = murrine_rgba_draw_tooltip; */
+	functions->draw_radiobutton        = murrine_rgba_draw_radiobutton;
+	functions->draw_checkbox           = murrine_rgba_draw_checkbox;
+	functions->draw_menu_frame         = murrine_rgba_draw_menu_frame;
+	functions->draw_statusbar          = murrine_rgba_draw_statusbar;
+}

Added: trunk/src/murrine_draw_rgba.h
==============================================================================
--- (empty file)
+++ trunk/src/murrine_draw_rgba.h	Mon Feb 11 23:01:49 2008
@@ -0,0 +1,37 @@
+/* Murrine theme engine
+ * Copyright (C) 2007 Andrea Cimitan
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ */
+
+#ifndef MURRINE_DRAW_RGBA_H
+#define MURRINE_DRAW_RGBA_H
+
+#include "murrine_types.h"
+
+#include <gtk/gtk.h>
+#include <gdk/gdk.h>
+
+#include <cairo.h>
+
+G_GNUC_INTERNAL void murrine_draw_button_rgba (cairo_t *cr,
+                                               const MurrineColors    *colors,
+                                               const WidgetParameters *widget,
+                                               int x, int y, int width, int height,
+                                               boolean vertical);
+
+#endif /* MURRINE_DRAW_RGBA_H */

Added: trunk/src/murrine_rc_style.c
==============================================================================
--- (empty file)
+++ trunk/src/murrine_rc_style.c	Mon Feb 11 23:01:49 2008
@@ -0,0 +1,643 @@
+/* Murrine theme engine
+ * Copyright (C) 2007 Andrea Cimitan
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include "murrine_style.h"
+#include "murrine_rc_style.h"
+
+#include "animation.h"
+
+static void murrine_rc_style_init (MurrineRcStyle *style);
+#ifdef HAVE_ANIMATION
+static void murrine_rc_style_finalize (GObject *object);
+#endif
+static void murrine_rc_style_class_init (MurrineRcStyleClass *klass);
+static GtkStyle *murrine_rc_style_create_style (GtkRcStyle *rc_style);
+static guint murrine_rc_style_parse (GtkRcStyle  *rc_style,
+                                     GtkSettings *settings,
+                                     GScanner    *scanner);
+static void murrine_rc_style_merge (GtkRcStyle *dest,
+                                    GtkRcStyle *src);
+
+static GtkRcStyleClass *parent_class;
+
+GType murrine_type_rc_style = 0;
+
+enum
+{
+	TOKEN_ANIMATION = G_TOKEN_LAST + 1,
+	TOKEN_COLORIZE_SCROLLBAR,
+	TOKEN_CONTRAST,
+	TOKEN_GLAZESTYLE,
+	TOKEN_GRADIENT_STOP_1,
+	TOKEN_GRADIENT_STOP_2,
+	TOKEN_GRADIENT_STOP_3,
+	TOKEN_GRADIENT_STOP_4,
+	TOKEN_GRADIENTS,
+	TOKEN_HIGHLIGHT_RATIO,
+	TOKEN_INNERBORDER_RATIO,
+	TOKEN_LISTVIEWHEADERSTYLE,
+	TOKEN_LISTVIEWSTYLE,
+	TOKEN_MENUBARITEMSTYLE,
+	TOKEN_MENUBARSTYLE,
+	TOKEN_MENUITEMSTYLE,
+	TOKEN_MENUSTYLE,
+	TOKEN_RGBA,
+	TOKEN_ROUNDNESS,
+	TOKEN_SCROLLBAR_COLOR,
+	TOKEN_SCROLLBARSTYLE,
+	TOKEN_SLIDERSTYLE,
+	TOKEN_STEPPERSTYLE,
+	TOKEN_STYLE,
+	TOKEN_TOOLBARSTYLE,
+
+	TOKEN_CANDIDO,
+	TOKEN_CLEARLOOKS,
+	TOKEN_MIST,
+	TOKEN_MURRINE,
+	TOKEN_NODOKA,
+
+	TOKEN_TRUE,
+	TOKEN_FALSE,
+
+	/* stuff to ignore */
+	TOKEN_HILIGHT_RATIO,
+	TOKEN_SQUAREDSTYLE
+};
+
+static struct
+{
+	const gchar *name;
+	guint        token;
+}
+theme_symbols[] =
+{
+	{ "animation",           TOKEN_ANIMATION },
+	{ "colorize_scrollbar",  TOKEN_COLORIZE_SCROLLBAR },
+	{ "contrast",            TOKEN_CONTRAST },
+	{ "glazestyle",          TOKEN_GLAZESTYLE },
+	{ "gradient_stop_1",     TOKEN_GRADIENT_STOP_1 },
+	{ "gradient_stop_2",     TOKEN_GRADIENT_STOP_2 },
+	{ "gradient_stop_3",     TOKEN_GRADIENT_STOP_3 },
+	{ "gradient_stop_4",     TOKEN_GRADIENT_STOP_4 },
+	{ "gradients",           TOKEN_GRADIENTS },
+	{ "highlight_ratio",     TOKEN_HIGHLIGHT_RATIO },
+	{ "innerborder_ratio",   TOKEN_INNERBORDER_RATIO },
+	{ "listviewheaderstyle", TOKEN_LISTVIEWHEADERSTYLE },
+	{ "listviewstyle",       TOKEN_LISTVIEWSTYLE },
+	{ "menubaritemstyle",    TOKEN_MENUBARITEMSTYLE },
+	{ "menubarstyle",        TOKEN_MENUBARSTYLE },
+	{ "menuitemstyle",       TOKEN_MENUITEMSTYLE },
+	{ "menustyle",           TOKEN_MENUSTYLE },
+	{ "rgba",                TOKEN_RGBA },
+	{ "roundness",           TOKEN_ROUNDNESS },
+	{ "scrollbar_color",     TOKEN_SCROLLBAR_COLOR },
+	{ "scrollbarstyle",      TOKEN_SCROLLBARSTYLE },
+	{ "sliderstyle",         TOKEN_SLIDERSTYLE },
+	{ "stepperstyle",        TOKEN_STEPPERSTYLE },
+	{ "style",               TOKEN_STYLE },
+	{ "toolbarstyle",        TOKEN_TOOLBARSTYLE },
+
+	{ "CANDIDO",             TOKEN_CANDIDO },
+	{ "CLEARLOOKS",          TOKEN_CLEARLOOKS },
+	{ "MIST",                TOKEN_MIST },
+	{ "MURRINE",             TOKEN_MURRINE },
+	{ "NODOKA",              TOKEN_NODOKA },
+
+	{ "TRUE",                TOKEN_TRUE },
+	{ "FALSE",               TOKEN_FALSE },
+
+	/* stuff to ignore */
+	{ "hilight_ratio",       TOKEN_HILIGHT_RATIO },
+	{ "squaredstyle",        TOKEN_SQUAREDSTYLE }
+};
+
+void
+murrine_rc_style_register_type (GTypeModule *module)
+{
+	static const GTypeInfo object_info =
+	{
+		sizeof (MurrineRcStyleClass),
+		(GBaseInitFunc) NULL,
+		(GBaseFinalizeFunc) NULL,
+		(GClassInitFunc) murrine_rc_style_class_init,
+		NULL, /* class_finalize */
+		NULL, /* class_data */
+		sizeof (MurrineRcStyle),
+		0, /* n_preallocs */
+		(GInstanceInitFunc) murrine_rc_style_init,
+		NULL
+	};
+
+	murrine_type_rc_style = g_type_module_register_type (module,
+	                                                     GTK_TYPE_RC_STYLE,
+	                                                     "MurrineRcStyle",
+	                                                     &object_info, 0);
+}
+
+static void
+murrine_rc_style_init (MurrineRcStyle *murrine_rc)
+{
+	murrine_rc->flags = 0;
+
+	murrine_rc->animation = FALSE;
+	murrine_rc->colorize_scrollbar = TRUE;
+	murrine_rc->contrast = 1.0;
+	murrine_rc->glazestyle = 1;
+	murrine_rc->gradient_stop_1 = 1.0;
+	murrine_rc->gradient_stop_2 = 1.0;
+	murrine_rc->gradient_stop_3 = 1.0;
+	murrine_rc->gradient_stop_4 = 1.0;
+	murrine_rc->gradients = TRUE;
+	murrine_rc->has_scrollbar_color = FALSE;
+	murrine_rc->has_gradient_stop = FALSE;
+	murrine_rc->highlight_ratio = 1.1;
+	murrine_rc->innerborder_ratio = 1.1;
+	murrine_rc->listviewheaderstyle = 1;
+	murrine_rc->listviewstyle = 0;
+	murrine_rc->menubaritemstyle = 0;
+	murrine_rc->menubarstyle = 0;
+	murrine_rc->menuitemstyle = 1;
+	murrine_rc->menustyle = 1;
+	murrine_rc->rgba = TRUE;
+	murrine_rc->roundness = 1;
+	murrine_rc->scrollbarstyle = 0;
+	murrine_rc->sliderstyle = 0;
+	murrine_rc->stepperstyle = 0;
+	murrine_rc->style = MRN_STYLE_MURRINE;
+	murrine_rc->toolbarstyle = 0;
+}
+
+#ifdef HAVE_ANIMATION
+static void
+murrine_rc_style_finalize (GObject *object)
+{
+	/* cleanup all the animation stuff */
+	murrine_animation_cleanup ();
+
+	if (G_OBJECT_CLASS (parent_class)->finalize != NULL)
+		G_OBJECT_CLASS (parent_class)->finalize(object);
+}
+#endif
+
+
+static void
+murrine_rc_style_class_init (MurrineRcStyleClass *klass)
+{
+	GtkRcStyleClass *rc_style_class = GTK_RC_STYLE_CLASS (klass);
+#ifdef HAVE_ANIMATION
+	GObjectClass    *g_object_class = G_OBJECT_CLASS (klass);
+#endif
+
+	parent_class = g_type_class_peek_parent (klass);
+
+	rc_style_class->parse = murrine_rc_style_parse;
+	rc_style_class->create_style = murrine_rc_style_create_style;
+	rc_style_class->merge = murrine_rc_style_merge;
+
+#ifdef HAVE_ANIMATION
+	g_object_class->finalize = murrine_rc_style_finalize;
+#endif
+}
+
+static guint
+theme_parse_boolean (GtkSettings *settings,
+                     GScanner     *scanner,
+                     gboolean *retval)
+{
+	guint token;
+
+	/* Skip 'ANIMATION' */
+	token = g_scanner_get_next_token(scanner);
+
+	token = g_scanner_get_next_token(scanner);
+	if (token != G_TOKEN_EQUAL_SIGN)
+		return G_TOKEN_EQUAL_SIGN;
+
+	token = g_scanner_get_next_token(scanner);
+	if (token == TOKEN_TRUE)
+		*retval = TRUE;
+	else if (token == TOKEN_FALSE)
+		*retval = FALSE;
+	else
+		return TOKEN_TRUE;
+
+	return G_TOKEN_NONE;
+}
+
+static guint
+theme_parse_color (GtkSettings  *settings,
+                   GScanner     *scanner,
+                   GdkColor     *color)
+{
+	guint token;
+
+	/* Skip 'blah_color' */
+	token = g_scanner_get_next_token(scanner);
+
+	token = g_scanner_get_next_token(scanner);
+	if (token != G_TOKEN_EQUAL_SIGN)
+		return G_TOKEN_EQUAL_SIGN;
+
+	return gtk_rc_parse_color (scanner, color);
+}
+
+static guint
+theme_parse_ratio (GtkSettings  *settings,
+                   GScanner     *scanner,
+                   double       *ratio)
+{
+	guint token;
+
+	/* Skip 'ratio' */
+	token = g_scanner_get_next_token(scanner);
+
+	token = g_scanner_get_next_token(scanner);
+	if (token != G_TOKEN_EQUAL_SIGN)
+		return G_TOKEN_EQUAL_SIGN;
+
+	token = g_scanner_get_next_token(scanner);
+	if (token != G_TOKEN_FLOAT)
+		return G_TOKEN_FLOAT;
+
+	*ratio = scanner->value.v_float;
+
+	return G_TOKEN_NONE;
+}
+
+static guint
+theme_parse_int (GtkSettings  *settings,
+                 GScanner     *scanner,
+                 guint8       *style)
+{
+	guint token;
+
+	/* Skip '*style' */
+	token = g_scanner_get_next_token(scanner);
+
+	token = g_scanner_get_next_token(scanner);
+	if (token != G_TOKEN_EQUAL_SIGN)
+	return G_TOKEN_EQUAL_SIGN;
+
+	token = g_scanner_get_next_token(scanner);
+	if (token != G_TOKEN_INT)
+		return G_TOKEN_INT;
+
+	*style = scanner->value.v_int;
+
+	return G_TOKEN_NONE;
+}
+
+static guint
+theme_parse_style (GtkSettings   *settings,
+                   GScanner      *scanner,
+                   MurrineStyles *style)
+{
+	guint token;
+
+	g_assert (MRN_NUM_STYLES == MRN_STYLE_CLEARLOOKS + 1); /* so that people don't forget ;-) */
+
+	/* Skip 'style' */
+	token = g_scanner_get_next_token (scanner);
+
+	token = g_scanner_get_next_token (scanner);
+	if (token != G_TOKEN_EQUAL_SIGN)
+	   return G_TOKEN_EQUAL_SIGN;
+
+	token = g_scanner_get_next_token (scanner);
+
+	switch (token)
+	{
+		case TOKEN_MURRINE:
+		   *style = MRN_STYLE_MURRINE;
+		   break;
+		case TOKEN_NODOKA:
+		   *style = MRN_STYLE_NODOKA;
+		   break;
+		case TOKEN_MIST:
+		   *style = MRN_STYLE_MIST;
+		   break;
+		case TOKEN_CANDIDO:
+		   *style = MRN_STYLE_CANDIDO;
+		   break;
+		case TOKEN_CLEARLOOKS:
+		   *style = MRN_STYLE_CLEARLOOKS;
+		   break;
+		default:
+		   return TOKEN_MURRINE;
+	}
+
+	return G_TOKEN_NONE;
+}
+
+static guint
+murrine_gtk2_rc_parse_dummy (GtkSettings      *settings,
+                             GScanner         *scanner,
+                             gchar            *name)
+{
+	guint token;
+
+	/* Skip option */
+	token = g_scanner_get_next_token (scanner);
+
+	/* print a warning. Isn't there a way to get the string from the scanner? */
+	g_scanner_warn (scanner, "Murrine configuration option \"%s\" is not supported and will be ignored.", name);
+
+	/* equal sign */
+	token = g_scanner_get_next_token (scanner);
+	if (token != G_TOKEN_EQUAL_SIGN)
+		return G_TOKEN_EQUAL_SIGN;
+
+	/* eat whatever comes next */
+	token = g_scanner_get_next_token (scanner);
+
+	return G_TOKEN_NONE;
+}
+
+static guint
+murrine_rc_style_parse (GtkRcStyle *rc_style,
+                        GtkSettings  *settings,
+                        GScanner   *scanner)
+{
+	static GQuark scope_id = 0;
+	MurrineRcStyle *murrine_style = MURRINE_RC_STYLE (rc_style);
+
+	guint old_scope;
+	guint token;
+	guint i;
+
+	/* Set up a new scope in this scanner. */
+
+	if (!scope_id)
+		scope_id = g_quark_from_string("murrine_theme_engine");
+
+	/* If we bail out due to errors, we *don't* reset the scope, so the
+	* error messaging code can make sense of our tokens.
+	*/
+	old_scope = g_scanner_set_scope(scanner, scope_id);
+
+	/* Now check if we already added our symbols to this scope
+	* (in some previous call to murrine_rc_style_parse for the
+	* same scanner.
+	*/
+
+	if (!g_scanner_lookup_symbol(scanner, theme_symbols[0].name))
+	{
+		g_scanner_freeze_symbol_table(scanner);
+		for (i = 0; i < G_N_ELEMENTS (theme_symbols); i++)
+			g_scanner_scope_add_symbol(scanner, scope_id, theme_symbols[i].name, GINT_TO_POINTER(theme_symbols[i].token));
+		g_scanner_thaw_symbol_table(scanner);
+	}
+
+	/* We're ready to go, now parse the top level */
+	token = g_scanner_peek_next_token(scanner);
+	while (token != G_TOKEN_RIGHT_CURLY)
+	{
+		switch (token)
+		{
+			case TOKEN_ANIMATION:
+				token = theme_parse_boolean (settings, scanner, &murrine_style->animation);
+				murrine_style->flags |= MRN_FLAG_ANIMATION;
+				break;
+			case TOKEN_COLORIZE_SCROLLBAR:
+				token = theme_parse_boolean (settings, scanner, &murrine_style->colorize_scrollbar);
+				murrine_style->flags |= MRN_FLAG_COLORIZE_SCROLLBAR;
+				break;
+			case TOKEN_CONTRAST:
+				token = theme_parse_ratio (settings, scanner, &murrine_style->contrast);
+				murrine_style->flags |= MRN_FLAG_CONTRAST;
+				break;
+			case TOKEN_GLAZESTYLE:
+				token = theme_parse_int (settings, scanner, &murrine_style->glazestyle);
+				murrine_style->flags |= MRN_FLAG_GLAZESTYLE;
+				break;
+			case TOKEN_GRADIENT_STOP_1:
+				token = theme_parse_ratio (settings, scanner, &murrine_style->gradient_stop_1);
+				murrine_style->flags |= MRN_FLAG_GRADIENT_STOP_1;
+				murrine_style->has_gradient_stop = TRUE;
+				break;
+			case TOKEN_GRADIENT_STOP_2:
+				token = theme_parse_ratio (settings, scanner, &murrine_style->gradient_stop_2);
+				murrine_style->flags |= MRN_FLAG_GRADIENT_STOP_2;
+				murrine_style->has_gradient_stop = TRUE;
+				break;
+			case TOKEN_GRADIENT_STOP_3:
+				token = theme_parse_ratio (settings, scanner, &murrine_style->gradient_stop_3);
+				murrine_style->flags |= MRN_FLAG_GRADIENT_STOP_3;
+				murrine_style->has_gradient_stop = TRUE;
+				break;
+			case TOKEN_GRADIENT_STOP_4:
+				token = theme_parse_ratio (settings, scanner, &murrine_style->gradient_stop_4);
+				murrine_style->flags |= MRN_FLAG_GRADIENT_STOP_4;
+				murrine_style->has_gradient_stop = TRUE;
+				break;
+			case TOKEN_GRADIENTS:
+				token = theme_parse_boolean (settings, scanner, &murrine_style->gradients);
+				murrine_style->flags |= MRN_FLAG_GRADIENTS;
+				break;
+			case TOKEN_HIGHLIGHT_RATIO:
+				token = theme_parse_ratio (settings, scanner, &murrine_style->highlight_ratio);
+				murrine_style->flags |= MRN_FLAG_HIGHLIGHT_RATIO;
+				break;
+			case TOKEN_INNERBORDER_RATIO:
+				token = theme_parse_ratio (settings, scanner, &murrine_style->innerborder_ratio);
+				murrine_style->flags |= MRN_FLAG_INNERBORDER_RATIO;
+				break;
+			case TOKEN_LISTVIEWHEADERSTYLE:
+				token = theme_parse_int (settings, scanner, &murrine_style->listviewheaderstyle);
+				murrine_style->flags |= MRN_FLAG_LISTVIEWHEADERSTYLE;
+				break;
+			case TOKEN_LISTVIEWSTYLE:
+				token = theme_parse_int (settings, scanner, &murrine_style->listviewstyle);
+				murrine_style->flags |= MRN_FLAG_LISTVIEWSTYLE;
+				break;
+			case TOKEN_MENUBARITEMSTYLE:
+				token = theme_parse_int (settings, scanner, &murrine_style->menubaritemstyle);
+				murrine_style->flags |= MRN_FLAG_MENUBARITEMSTYLE;
+				break;
+			case TOKEN_MENUBARSTYLE:
+				token = theme_parse_int (settings, scanner, &murrine_style->menubarstyle);
+				murrine_style->flags |= MRN_FLAG_MENUBARSTYLE;
+				break;
+			case TOKEN_MENUITEMSTYLE:
+				token = theme_parse_int (settings, scanner, &murrine_style->menuitemstyle);
+				murrine_style->flags |= MRN_FLAG_MENUITEMSTYLE;
+				break;
+			case TOKEN_MENUSTYLE:
+				token = theme_parse_int (settings, scanner, &murrine_style->menustyle);
+				murrine_style->flags |= MRN_FLAG_MENUSTYLE;
+				break;
+			case TOKEN_RGBA:
+				token = theme_parse_boolean (settings, scanner, &murrine_style->rgba);
+				murrine_style->flags |= MRN_FLAG_RGBA;
+				break;
+			case TOKEN_ROUNDNESS:
+				token = theme_parse_int (settings, scanner, &murrine_style->roundness);
+				murrine_style->flags |= MRN_FLAG_ROUNDNESS;
+				break;
+			case TOKEN_SCROLLBAR_COLOR:
+				token = theme_parse_color (settings, scanner, &murrine_style->scrollbar_color);
+				murrine_style->flags |= MRN_FLAG_SCROLLBAR_COLOR;
+				murrine_style->has_scrollbar_color = TRUE;
+				break;
+			case TOKEN_SCROLLBARSTYLE:
+				token = theme_parse_int (settings, scanner, &murrine_style->scrollbarstyle);
+				murrine_style->flags |= MRN_FLAG_SCROLLBARSTYLE;
+				break;
+			case TOKEN_SLIDERSTYLE:
+				token = theme_parse_int (settings, scanner, &murrine_style->sliderstyle);
+				murrine_style->flags |= MRN_FLAG_SLIDERSTYLE;
+				break;
+			case TOKEN_STEPPERSTYLE:
+				token = theme_parse_int (settings, scanner, &murrine_style->stepperstyle);
+				murrine_style->flags |= MRN_FLAG_STEPPERSTYLE;
+				break;
+			case TOKEN_STYLE:
+				token = theme_parse_style (settings, scanner, &murrine_style->style);
+				murrine_style->flags |= MRN_FLAG_STYLE;
+				break;
+			case TOKEN_TOOLBARSTYLE:
+				token = theme_parse_int (settings, scanner, &murrine_style->toolbarstyle);
+				murrine_style->flags |= MRN_FLAG_TOOLBARSTYLE;
+				break;
+
+			/* stuff to ignore */
+			case TOKEN_HILIGHT_RATIO:
+				g_scanner_warn (scanner, "Murrine configuration option \"hilight_ratio\" will be deprecated in future releases. Please update this theme to get rid of this warning.", "hilight_ratio");
+				double hilight_ratio;
+				token = theme_parse_ratio (settings, scanner, &hilight_ratio);
+				murrine_style->highlight_ratio = hilight_ratio/0.909090;
+				murrine_style->flags |= MRN_FLAG_HIGHLIGHT_RATIO;
+				break;
+			case TOKEN_SQUAREDSTYLE:
+				token = murrine_gtk2_rc_parse_dummy (settings, scanner, "squaredstyle");
+				break;
+
+			default:
+				g_scanner_get_next_token(scanner);
+				token = G_TOKEN_RIGHT_CURLY;
+				break;
+		}
+
+		if (token != G_TOKEN_NONE)
+			return token;
+
+		token = g_scanner_peek_next_token(scanner);
+	}
+
+	g_scanner_get_next_token(scanner);
+
+	g_scanner_set_scope(scanner, old_scope);
+
+	return G_TOKEN_NONE;
+}
+
+static void
+murrine_rc_style_merge (GtkRcStyle *dest,
+                        GtkRcStyle *src)
+{
+	MurrineRcStyle *dest_w, *src_w;
+	MurrineRcFlags flags;
+
+	parent_class->merge (dest, src);
+
+	if (!MURRINE_IS_RC_STYLE (src))
+		return;
+
+	src_w = MURRINE_RC_STYLE (src);
+	dest_w = MURRINE_RC_STYLE (dest);
+
+	flags = (~dest_w->flags) & src_w->flags;
+
+	if (flags & MRN_FLAG_ANIMATION)
+		dest_w->animation = src_w->animation;
+	if (flags & MRN_FLAG_COLORIZE_SCROLLBAR)
+		dest_w->colorize_scrollbar = src_w->colorize_scrollbar;
+	if (flags & MRN_FLAG_CONTRAST)
+		dest_w->contrast = src_w->contrast;
+	if (flags & MRN_FLAG_GLAZESTYLE)
+		dest_w->glazestyle = src_w->glazestyle;
+	if (flags & MRN_FLAG_GRADIENT_STOP_1)
+	{
+		dest_w->has_gradient_stop = TRUE;
+		dest_w->gradient_stop_1 = src_w->gradient_stop_1;
+	}
+	if (flags & MRN_FLAG_GRADIENT_STOP_2)
+	{
+		dest_w->has_gradient_stop = TRUE;
+		dest_w->gradient_stop_2 = src_w->gradient_stop_2;
+	}
+	if (flags & MRN_FLAG_GRADIENT_STOP_3)
+	{
+		dest_w->has_gradient_stop = TRUE;
+		dest_w->gradient_stop_3 = src_w->gradient_stop_3;
+	}
+	if (flags & MRN_FLAG_GRADIENT_STOP_4)
+	{
+		dest_w->has_gradient_stop = TRUE;
+		dest_w->gradient_stop_4 = src_w->gradient_stop_4;
+	}
+	if (flags & MRN_FLAG_GRADIENTS)
+		dest_w->gradients = src_w->gradients;
+	if (flags & MRN_FLAG_HIGHLIGHT_RATIO)
+		dest_w->highlight_ratio = src_w->highlight_ratio;
+	if (flags & MRN_FLAG_INNERBORDER_RATIO)
+		dest_w->innerborder_ratio = src_w->innerborder_ratio;
+	if (flags & MRN_FLAG_LISTVIEWHEADERSTYLE)
+		dest_w->listviewheaderstyle = src_w->listviewheaderstyle;
+	if (flags & MRN_FLAG_LISTVIEWSTYLE)
+		dest_w->listviewstyle = src_w->listviewstyle;
+	if (flags & MRN_FLAG_MENUBARITEMSTYLE)
+		dest_w->menubaritemstyle = src_w->menubaritemstyle;
+	if (flags & MRN_FLAG_MENUBARSTYLE)
+		dest_w->menubarstyle = src_w->menubarstyle;
+	if (flags & MRN_FLAG_MENUITEMSTYLE)
+		dest_w->menuitemstyle = src_w->menuitemstyle;
+	if (flags & MRN_FLAG_MENUSTYLE)
+		dest_w->menustyle = src_w->menustyle;
+	if (flags & MRN_FLAG_RGBA)
+		dest_w->rgba = src_w->rgba;
+	if (flags & MRN_FLAG_ROUNDNESS)
+		dest_w->roundness = src_w->roundness;
+	if (flags & MRN_FLAG_SCROLLBAR_COLOR)
+	{
+		dest_w->has_scrollbar_color = TRUE;
+		dest_w->scrollbar_color = src_w->scrollbar_color;
+	}
+	if (flags & MRN_FLAG_SCROLLBARSTYLE)
+		dest_w->scrollbarstyle = src_w->scrollbarstyle;
+	if (flags & MRN_FLAG_SLIDERSTYLE)
+		dest_w->sliderstyle = src_w->sliderstyle;
+	if (flags & MRN_FLAG_STEPPERSTYLE)
+		dest_w->stepperstyle = src_w->stepperstyle;
+	if (flags & MRN_FLAG_STYLE)
+		dest_w->style = src_w->style;
+	if (flags & MRN_FLAG_TOOLBARSTYLE)
+		dest_w->toolbarstyle = src_w->toolbarstyle;
+
+	dest_w->flags |= src_w->flags;
+}
+
+/* Create an empty style suitable to this RC style
+ */
+static GtkStyle *
+murrine_rc_style_create_style (GtkRcStyle *rc_style)
+{
+	return GTK_STYLE (g_object_new (MURRINE_TYPE_STYLE, NULL));
+}

Added: trunk/src/murrine_rc_style.h
==============================================================================
--- (empty file)
+++ trunk/src/murrine_rc_style.h	Mon Feb 11 23:01:49 2008
@@ -0,0 +1,108 @@
+/* Murrine theme engine
+ * Copyright (C) 2007 Andrea Cimitan
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include <gtk/gtkrc.h>
+
+typedef struct _MurrineRcStyle MurrineRcStyle;
+typedef struct _MurrineRcStyleClass MurrineRcStyleClass;
+
+G_GNUC_INTERNAL extern GType murrine_type_rc_style;
+
+#define MURRINE_TYPE_RC_STYLE              murrine_type_rc_style
+#define MURRINE_RC_STYLE(object)           (G_TYPE_CHECK_INSTANCE_CAST ((object), MURRINE_TYPE_RC_STYLE, MurrineRcStyle))
+#define MURRINE_RC_STYLE_CLASS(klass)      (G_TYPE_CHECK_CLASS_CAST ((klass), MURRINE_TYPE_RC_STYLE, MurrineRcStyleClass))
+#define MURRINE_IS_RC_STYLE(object)        (G_TYPE_CHECK_INSTANCE_TYPE ((object), MURRINE_TYPE_RC_STYLE))
+#define MURRINE_IS_RC_STYLE_CLASS(klass)   (G_TYPE_CHECK_CLASS_TYPE ((klass), MURRINE_TYPE_RC_STYLE))
+#define MURRINE_RC_STYLE_GET_CLASS(obj)    (G_TYPE_INSTANCE_GET_CLASS ((obj), MURRINE_TYPE_RC_STYLE, MurrineRcStyleClass))
+
+typedef enum
+{
+	MRN_FLAG_ANIMATION = 1 << 0,
+	MRN_FLAG_COLORIZE_SCROLLBAR = 1 << 1,
+	MRN_FLAG_CONTRAST = 1 << 2,
+	MRN_FLAG_GLAZESTYLE = 1 << 3,
+	MRN_FLAG_GRADIENT_STOP_1 = 1 << 4,
+	MRN_FLAG_GRADIENT_STOP_2 = 1 << 5,
+	MRN_FLAG_GRADIENT_STOP_3 = 1 << 6,
+	MRN_FLAG_GRADIENT_STOP_4 = 1 << 7,
+	MRN_FLAG_GRADIENTS = 1 << 8,
+	MRN_FLAG_HIGHLIGHT_RATIO = 1 << 9,
+	MRN_FLAG_INNERBORDER_RATIO = 1 << 10,
+	MRN_FLAG_LISTVIEWHEADERSTYLE = 1 << 11,
+	MRN_FLAG_LISTVIEWSTYLE = 1 << 12,
+	MRN_FLAG_MENUBARITEMSTYLE = 1 << 13,
+	MRN_FLAG_MENUBARSTYLE = 1 << 14,
+	MRN_FLAG_MENUITEMSTYLE = 1 << 15,
+	MRN_FLAG_MENUSTYLE = 1 << 16,
+	MRN_FLAG_RGBA = 1 << 17,
+	MRN_FLAG_ROUNDNESS = 1 << 18,
+	MRN_FLAG_SCROLLBAR_COLOR = 1 << 19,
+	MRN_FLAG_SCROLLBARSTYLE = 1 << 20,
+	MRN_FLAG_SLIDERSTYLE = 1 << 21,
+	MRN_FLAG_STEPPERSTYLE = 1 << 22,
+	MRN_FLAG_STYLE = 1 << 23,
+	MRN_FLAG_TOOLBARSTYLE = 1 << 24
+} MurrineRcFlags;
+
+struct _MurrineRcStyle
+{
+	GtkRcStyle parent_instance;
+
+	MurrineRcFlags flags;
+
+	double   contrast;
+	double   gradient_stop_1;
+	double   gradient_stop_2;
+	double   gradient_stop_3;
+	double   gradient_stop_4;
+	double   highlight_ratio;
+	double   innerborder_ratio;
+
+	guint8   glazestyle;
+	guint8   listviewheaderstyle;
+	guint8   listviewstyle;
+	guint8   menubaritemstyle;
+	guint8   menubarstyle;
+	guint8   menuitemstyle;
+	guint8   menustyle;
+	guint8   roundness;
+	guint8   scrollbarstyle;
+	guint8   sliderstyle;
+	guint8   stepperstyle;
+	guint8   toolbarstyle;
+
+	gboolean animation;
+	gboolean gradients;
+	gboolean colorize_scrollbar;
+	gboolean has_gradient_stop;
+	gboolean has_scrollbar_color;
+	gboolean rgba;
+
+	GdkColor scrollbar_color;
+
+	MurrineStyles style;
+};
+
+struct _MurrineRcStyleClass
+{
+	GtkRcStyleClass parent_class;
+};
+
+G_GNUC_INTERNAL void murrine_rc_style_register_type (GTypeModule *module);

Added: trunk/src/murrine_style.c
==============================================================================
--- (empty file)
+++ trunk/src/murrine_style.c	Mon Feb 11 23:01:49 2008
@@ -0,0 +1,2088 @@
+/* Murrine theme engine
+ * Copyright (C) 2007 Andrea Cimitan
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include <gtk/gtk.h>
+#include <cairo.h>
+#include <math.h>
+#include <string.h>
+#include <sys/time.h>
+
+#include "murrine_style.h"
+#include "murrine_rc_style.h"
+#include "murrine_draw.h"
+#include "support.h"
+#include "cairo-support.h"
+
+/* #define DEBUG 1 */
+
+#define SCALE_SIZE 5
+
+#define DETAIL(xx) ((detail) && (!strcmp(xx, detail)))
+#define COMPARE_COLORS(a,b) (a.red == b.red && a.green == b.green && a.blue == b.blue)
+
+#define DRAW_ARGS GtkStyle      *style, \
+                  GdkWindow     *window, \
+                  GtkStateType  state_type, \
+                  GtkShadowType shadow_type, \
+                  GdkRectangle  *area, \
+                  GtkWidget     *widget, \
+                  const gchar   *detail, \
+                  gint          x, \
+                  gint          y, \
+                  gint          width, \
+                  gint          height
+
+#define CHECK_ARGS \
+	g_return_if_fail (window != NULL); \
+	g_return_if_fail (style != NULL);
+
+#define SANITIZE_SIZE \
+	g_return_if_fail (width  >= -1); \
+	g_return_if_fail (height >= -1); \
+	\
+	if ((width == -1) && (height == -1)) \
+		gdk_drawable_get_size (window, &width, &height); \
+	else if (width == -1) \
+		gdk_drawable_get_size (window, &width, NULL); \
+	else if (height == -1) \
+		gdk_drawable_get_size (window, NULL, &height);
+
+#ifdef HAVE_ANIMATION
+#include "animation.h"
+#endif
+
+#define STYLE_FUNCTION(function) (murrine_style_class->style_functions[params.drawstyle].function)
+
+static MurrineStyleClass *murrine_style_class;
+static GtkStyleClass *murrine_parent_class;
+
+static cairo_t *
+murrine_begin_paint (GdkDrawable *window, GdkRectangle *area)
+{
+	cairo_t *cr;
+
+	g_return_val_if_fail (window != NULL, NULL);
+
+	cr = (cairo_t*) gdk_cairo_create (window);
+	cairo_set_line_width (cr, 1.0);
+
+	if (area)
+	{
+		cairo_rectangle (cr, area->x, area->y, area->width, area->height);
+		cairo_clip_preserve (cr);
+		cairo_new_path (cr);
+	}
+
+	return cr;
+}
+
+static
+boolean murrine_widget_is_rgba (GtkWidget *widget)
+{
+	GdkScreen *screen = gtk_widget_get_screen (widget);
+	boolean use_rgba = FALSE;
+
+	if (gdk_screen_is_composited(screen) && gdk_screen_get_rgba_colormap (screen))
+		use_rgba = (gtk_widget_get_colormap (widget) ==
+		            gdk_screen_get_rgba_colormap (screen));
+
+	return use_rgba;
+}
+
+static void
+murrine_set_widget_parameters (const GtkWidget  *widget,
+                               const GtkStyle   *style,
+                               GtkStateType     state_type,
+                               WidgetParameters *params)
+{
+	if (widget && MRN_IS_ENTRY (widget))
+		state_type = GTK_WIDGET_STATE (widget);
+
+	MurrineStyle *murrine_style = MURRINE_STYLE (style);
+
+	params->active     = (state_type == GTK_STATE_ACTIVE);
+	params->prelight   = (state_type == GTK_STATE_PRELIGHT);
+	params->disabled   = (state_type == GTK_STATE_INSENSITIVE);
+	params->state_type = (MurrineStateType)state_type;
+	params->corners    = MRN_CORNER_ALL;
+	params->ltr        = murrine_widget_is_ltr ((GtkWidget*)widget);
+	params->focus      = widget && GTK_WIDGET_HAS_FOCUS (widget);
+	params->is_default = widget && GTK_WIDGET_HAS_DEFAULT (widget);
+
+	if (!params->active && widget && MRN_IS_TOGGLE_BUTTON (widget))
+		params->active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget));
+
+	params->xthickness = style->xthickness;
+	params->ythickness = style->ythickness;
+
+	params->innerborder_ratio = murrine_style->innerborder_ratio;
+	params->glazestyle        = murrine_style->glazestyle;
+	params->roundness         = murrine_style->roundness;
+	params->highlight_ratio   = murrine_style->highlight_ratio;
+
+	MurrineGradients mrn_gradient;
+	mrn_gradient.has_gradient_stop = murrine_style->has_gradient_stop;
+	mrn_gradient.gradient_stop_1 = murrine_style->gradient_stop_1;
+	mrn_gradient.gradient_stop_2 = murrine_style->gradient_stop_2;
+	mrn_gradient.gradient_stop_3 = murrine_style->gradient_stop_3;
+	mrn_gradient.gradient_stop_4 = murrine_style->gradient_stop_4;
+	mrn_gradient.gradients = murrine_style->gradients;
+	mrn_gradient.use_rgba = (murrine_widget_is_rgba ((GtkWidget*) widget) && murrine_style->rgba);
+	mrn_gradient.rgba_opacity = GRADIENT_OPACITY;
+
+	MurrineDrawStyles drawstyle = MRN_DRAW_STYLE_MURRINE;
+	if (mrn_gradient.use_rgba)
+	{
+		//params->highlight_ratio = get_increased_ratio (params->highlight_ratio, 1.4);
+		drawstyle = MRN_DRAW_STYLE_RGBA;
+	}
+	params->mrn_gradient = mrn_gradient;
+	params->drawstyle = drawstyle;
+	params->style_functions = &(murrine_style_class->style_functions[drawstyle]);
+
+	/* I want to avoid to have to do this. I need it for GtkEntry, unless I
+	   find out why it doesn't behave the way I expect it to. */
+	params->parentbg = MURRINE_STYLE (style)->colors.bg[state_type];
+	murrine_get_parent_bg (widget, &params->parentbg);
+}
+
+static void
+murrine_style_draw_flat_box (DRAW_ARGS)
+{
+	//printf( "draw_flat_box: %s %s\n", detail, G_OBJECT_TYPE_NAME (widget));
+	if (detail &&
+	    state_type == GTK_STATE_SELECTED && (
+	    !strncmp ("cell_even", detail, 9) ||
+	    !strncmp ("cell_odd", detail, 8)))
+	{
+		MurrineStyle  *murrine_style = MURRINE_STYLE (style);
+		MurrineColors *colors = &murrine_style->colors;
+		cairo_t       *cr;
+
+		CHECK_ARGS
+		SANITIZE_SIZE
+
+		cr = murrine_begin_paint (window, area);
+
+		WidgetParameters params;
+
+		murrine_set_widget_parameters (widget, style, state_type, &params);
+
+		STYLE_FUNCTION(draw_selected_cell) (cr, colors, &params, x, y, width, height);
+
+		cairo_destroy (cr);
+	}
+	else if (DETAIL ("tooltip"))
+	{
+		MurrineStyle  *murrine_style = MURRINE_STYLE (style);
+		MurrineColors *colors = &murrine_style->colors;
+		cairo_t       *cr;
+
+		CHECK_ARGS
+		SANITIZE_SIZE
+
+		cr = murrine_begin_paint (window, area);
+
+		WidgetParameters params;
+
+		murrine_set_widget_parameters (widget, style, state_type, &params);
+
+		STYLE_FUNCTION(draw_tooltip) (cr, colors, &params, x, y, width, height);
+
+		cairo_destroy (cr);
+	}
+	else
+	{
+		if (DETAIL ("base") || DETAIL ("eventbox") || DETAIL ("entry_bg") || DETAIL ("trough"))
+		{
+			MurrineStyle  *murrine_style = MURRINE_STYLE (style);
+			MurrineColors *colors = &murrine_style->colors;
+			cairo_t       *cr;
+			boolean use_rgba = FALSE;
+
+			CHECK_ARGS
+			SANITIZE_SIZE
+
+			use_rgba = (murrine_widget_is_rgba (widget) && murrine_style->rgba);
+
+			if (!use_rgba)
+			{
+				murrine_parent_class->draw_flat_box (style, window, state_type,
+				                                     shadow_type,
+				                                     area, widget, detail,
+				                                     x, y, width, height);
+			}
+			else
+			{
+				cr = (cairo_t*) gdk_cairo_create (window);
+
+				if (DETAIL ("entry_bg"))
+				{
+					/* Draw (erase) the background */
+					cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR);
+					cairo_paint (cr);
+					cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
+
+					murrine_set_color_rgba (cr, &colors->base[state_type], ENTRY_OPACITY);
+					cairo_rectangle (cr, 0, 0, width, height);
+					cairo_fill (cr);
+				}
+				else if (DETAIL ("eventbox") || DETAIL ("trough"))
+				{
+					/* Draw (erase) the background */
+					cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR);
+					cairo_paint (cr);
+					cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
+
+					murrine_set_color_rgba (cr, &colors->bg[0], WINDOW_OPACITY);
+					cairo_rectangle (cr, 0, 0, width, height);
+					cairo_fill (cr);
+				}
+				else
+				{
+					/* Draw (erase) the background */
+					cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR);
+					cairo_paint (cr);
+					cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
+
+					cairo_pattern_t *pattern;
+
+					pattern = cairo_pattern_create_linear (0, 0, width, 0);
+					cairo_pattern_add_color_stop_rgba (pattern, 0.0, colors->bg[0].r,
+					                                                 colors->bg[0].g,
+					                                                 colors->bg[0].b, WINDOW_OPACITY);
+					cairo_pattern_add_color_stop_rgba (pattern, 0.5, colors->bg[0].r,
+					                                                 colors->bg[0].g,
+					                                                 colors->bg[0].b, 0.8);
+					cairo_pattern_add_color_stop_rgba (pattern, 1.0, colors->bg[0].r,
+					                                                 colors->bg[0].g,
+					                                                 colors->bg[0].b, WINDOW_OPACITY);
+					cairo_set_source (cr, pattern);
+					cairo_rectangle  (cr, 0, 0, width, height);
+					cairo_fill       (cr);
+					cairo_pattern_destroy (pattern);
+				}
+
+				cairo_destroy (cr);
+			}
+		}
+		else
+		{
+			// printf( "draw_flat_box: %s %s\n", detail, G_OBJECT_TYPE_NAME (widget));
+			murrine_parent_class->draw_flat_box (style, window, state_type,
+			                                     shadow_type,
+			                                     area, widget, detail,
+			                                     x, y, width, height);
+		}
+	}
+
+	/* Dotted listview */
+	if (detail && (!strncmp ("cell_even", detail, 9) || !strncmp ("cell_odd", detail, 8)))
+	{
+		MurrineStyle  *murrine_style = MURRINE_STYLE (style);
+		if (murrine_style->listviewstyle > 0)
+		{
+			MurrineColors *colors = &murrine_style->colors;
+			cairo_t       *cr;
+
+			CHECK_ARGS
+			SANITIZE_SIZE
+
+			cr = murrine_begin_paint (window, area);
+
+			cairo_translate (cr, x, y);
+			int i;
+			int pos = 1;
+			if (murrine_style->listviewheaderstyle != 1)
+				pos = 2;
+
+			murrine_set_color_rgba (cr, &colors->text[GTK_STATE_NORMAL], 0.42);
+			for (i = 2; i < height; i+=4)
+			{
+				cairo_rectangle (cr, -pos, i, 1, 1);
+				cairo_fill (cr);
+			}
+
+			cairo_destroy (cr);
+		}
+	}
+}
+
+static void
+murrine_style_draw_shadow (DRAW_ARGS)
+{
+	MurrineStyle  *murrine_style = MURRINE_STYLE (style);
+	MurrineColors *colors = &murrine_style->colors;
+	cairo_t       *cr;
+
+	CHECK_ARGS
+	SANITIZE_SIZE
+
+	cr = murrine_begin_paint (window, area);
+
+	if (DETAIL ("entry") && !(widget && widget->parent && MRN_IS_TREE_VIEW (widget->parent)))
+	{
+		WidgetParameters params;
+
+		murrine_set_widget_parameters (widget, style, state_type, &params);
+		params.roundness = murrine_style->roundness;
+
+		if (widget && (MRN_IS_COMBO (widget->parent) ||
+		               MRN_IS_COMBO_BOX_ENTRY(widget->parent) ||
+		               MRN_IS_SPIN_BUTTON (widget)))
+		{
+			width += style->xthickness;
+			if (!params.ltr)
+				x -= style->xthickness;
+
+			if (params.ltr)
+				params.corners = MRN_CORNER_TOPLEFT | MRN_CORNER_BOTTOMLEFT;
+			else
+				params.corners = MRN_CORNER_TOPRIGHT | MRN_CORNER_BOTTOMRIGHT;
+		}
+
+		STYLE_FUNCTION(draw_entry) (cr, &murrine_style->colors, &params,
+		                    x, y, width, height);
+	}
+	else if (DETAIL ("frame") && widget && MRN_IS_STATUSBAR (widget->parent))
+	{
+		WidgetParameters params;
+
+		murrine_set_widget_parameters (widget, style, state_type, &params);
+
+		if (!params.mrn_gradient.use_rgba)
+		{
+			gtk_style_apply_default_background (style, window, TRUE, state_type,
+			                                    area, x, y, width, height);
+		}
+
+		STYLE_FUNCTION(draw_statusbar) (cr, colors, &params,
+		                                x, y, width, height);
+	}
+	else if (DETAIL ("frame"))
+	{
+		WidgetParameters params;
+		FrameParameters  frame;
+
+		frame.shadow  = shadow_type;
+		frame.gap_x   = -1; /* No gap will be drawn */
+		frame.border  = &colors->shade[4];
+
+		murrine_set_widget_parameters (widget, style, state_type, &params);
+		params.corners = MRN_CORNER_NONE;
+
+		if (widget && !g_str_equal ("XfcePanelWindow", gtk_widget_get_name (gtk_widget_get_toplevel (widget))))
+			STYLE_FUNCTION(draw_frame) (cr, colors, &params, &frame, x, y, width, height);
+	}
+	else if (DETAIL ("scrolled_window") || DETAIL ("viewport") || detail == NULL)
+	{
+		MurrineRGB *border = (MurrineRGB*)&colors->shade[5];
+		cairo_rectangle (cr, x+0.5, y+0.5, width-1, height-1);
+		murrine_set_color_rgb (cr, border);
+		cairo_set_line_width (cr, 1);
+		cairo_stroke (cr);
+	}
+	else
+	{
+		WidgetParameters params;
+		FrameParameters frame;
+
+		frame.shadow = shadow_type;
+		frame.gap_x  = -1;
+		frame.border = &colors->shade[4];
+
+		murrine_set_widget_parameters (widget, style, state_type, &params);
+
+		params.corners = MRN_CORNER_ALL;
+		if (params.roundness < 2)
+			params.corners = MRN_CORNER_NONE;
+
+		STYLE_FUNCTION(draw_frame) (cr, colors, &params, &frame, x, y, width, height);
+	}
+
+	cairo_destroy (cr);
+}
+
+static void
+murrine_style_draw_box_gap (DRAW_ARGS,
+                            GtkPositionType gap_side,
+                            gint            gap_x,
+                            gint            gap_width)
+{
+	MurrineStyle  *murrine_style = MURRINE_STYLE (style);
+	MurrineColors *colors = &murrine_style->colors;
+	cairo_t       *cr;
+
+	CHECK_ARGS
+	SANITIZE_SIZE
+
+	cr = murrine_begin_paint (window, area);
+
+	if (DETAIL ("notebook"))
+	{
+		WidgetParameters params;
+		FrameParameters  frame;
+		gboolean start, end;
+
+		frame.shadow    = shadow_type;
+		frame.gap_side  = gap_side;
+		frame.gap_x     = gap_x;
+		frame.gap_width = gap_width;
+		frame.border    = &colors->shade[5];
+
+		murrine_set_widget_parameters (widget, style, state_type, &params);
+
+		murrine_get_notebook_tab_position (widget, &start, &end);
+
+		params.corners = MRN_CORNER_ALL;
+		switch (gap_side)
+		{
+			case GTK_POS_TOP:
+				if (murrine_widget_is_ltr (widget))
+				{
+					if (start)
+						params.corners ^= MRN_CORNER_TOPLEFT;
+					if (end)
+						params.corners ^= MRN_CORNER_TOPRIGHT;
+				}
+				else
+				{
+					if (start)
+						params.corners ^= MRN_CORNER_TOPRIGHT;
+					if (end)
+						params.corners ^= MRN_CORNER_TOPLEFT;
+				}
+				break;
+			case GTK_POS_BOTTOM:
+				if (murrine_widget_is_ltr (widget))
+				{
+					if (start)
+						params.corners ^= MRN_CORNER_BOTTOMLEFT;
+					if (end)
+						params.corners ^= MRN_CORNER_BOTTOMRIGHT;
+				}
+				else
+				{
+					if (start)
+						params.corners ^= MRN_CORNER_BOTTOMRIGHT;
+					if (end)
+						params.corners ^= MRN_CORNER_BOTTOMLEFT;
+				}
+				break;
+			case GTK_POS_LEFT:
+				if (start)
+					params.corners ^= MRN_CORNER_TOPLEFT;
+				if (end)
+					params.corners ^= MRN_CORNER_BOTTOMLEFT;
+				break;
+			case GTK_POS_RIGHT:
+				if (start)
+					params.corners ^= MRN_CORNER_TOPRIGHT;
+				if (end)
+					params.corners ^= MRN_CORNER_BOTTOMRIGHT;
+				break;
+		}
+		if (params.roundness < 2)
+			params.corners = MRN_CORNER_NONE;
+
+		/* Fill the background with bg[NORMAL] */
+		murrine_rounded_rectangle (cr, x, y, width, height, params.roundness, params.corners);
+		if (!params.mrn_gradient.use_rgba)
+			murrine_set_color_rgb (cr, &colors->bg[0]);
+		else
+			murrine_set_color_rgba (cr, &colors->bg[0], NOTEBOOK_OPACITY);
+		cairo_fill(cr);
+
+		STYLE_FUNCTION(draw_frame) (cr, colors, &params, &frame,
+		                            x, y, width, height);
+	}
+	else
+	{
+		murrine_parent_class->draw_box_gap (style, window, state_type, shadow_type,
+		                                    area, widget, detail,
+		                                    x, y, width, height,
+		                                    gap_side, gap_x, gap_width);
+	}
+
+	cairo_destroy (cr);
+}
+
+static void
+murrine_style_draw_extension (DRAW_ARGS, GtkPositionType gap_side)
+{
+	MurrineStyle  *murrine_style = MURRINE_STYLE (style);
+	MurrineColors *colors = &murrine_style->colors;
+	cairo_t       *cr;
+
+	CHECK_ARGS
+	SANITIZE_SIZE
+
+	cr = murrine_begin_paint (window, area);
+
+	if (DETAIL ("tab"))
+	{
+		WidgetParameters params;
+		TabParameters    tab;
+
+		murrine_set_widget_parameters (widget, style, state_type, &params);
+
+		tab.gap_side = (MurrineGapSide)gap_side;
+		switch (gap_side)
+		{
+			case MRN_GAP_TOP:
+				params.corners = MRN_CORNER_BOTTOMLEFT | MRN_CORNER_BOTTOMRIGHT;
+				break;
+			case MRN_GAP_BOTTOM:
+				params.corners = MRN_CORNER_TOPLEFT | MRN_CORNER_TOPRIGHT;
+				break;
+			case MRN_GAP_LEFT:
+				params.corners = MRN_CORNER_TOPRIGHT | MRN_CORNER_BOTTOMRIGHT;
+				break;
+			case MRN_GAP_RIGHT:
+				params.corners = MRN_CORNER_TOPLEFT | MRN_CORNER_BOTTOMLEFT;
+				break;
+		}
+
+		STYLE_FUNCTION(draw_tab) (cr, colors, &params, &tab, x, y, width, height);
+	}
+	else
+	{
+		murrine_parent_class->draw_extension (style, window, state_type, shadow_type, area,
+		                                      widget, detail, x, y, width, height, gap_side);
+	}
+
+	cairo_destroy (cr);
+}
+
+static void
+murrine_style_draw_handle (DRAW_ARGS, GtkOrientation orientation)
+{
+	MurrineStyle  *murrine_style = MURRINE_STYLE (style);
+	MurrineColors *colors = &murrine_style->colors;
+	cairo_t       *cr;
+	gboolean      is_horizontal;
+
+	CHECK_ARGS
+	SANITIZE_SIZE
+
+	cr = murrine_begin_paint (window, area);
+
+	/* Evil hack to work around broken orientation for toolbars */
+	is_horizontal = (width > height);
+
+	if (DETAIL ("handlebox"))
+	{
+		WidgetParameters params;
+		HandleParameters handle;
+
+		handle.type = MRN_HANDLE_TOOLBAR;
+		handle.horizontal = is_horizontal;
+
+		murrine_set_widget_parameters (widget, style, state_type, &params);
+
+		/* Is this ever true? -Daniel */
+		if (MRN_IS_TOOLBAR (widget) && shadow_type != GTK_SHADOW_NONE)
+		{
+			ToolbarParameters toolbar;
+
+			murrine_set_toolbar_parameters (&toolbar, widget, window, x, y);
+			toolbar.style = murrine_style->toolbarstyle;
+
+			if (params.mrn_gradient.use_rgba)
+			{
+				params.mrn_gradient.rgba_opacity = TOOLBAR_GLOSSY_OPACITY;
+			}
+
+			cairo_save (cr);
+			STYLE_FUNCTION(draw_toolbar) (cr, colors, &params, &toolbar, x, y, width, height);
+			cairo_restore (cr);
+		}
+
+		STYLE_FUNCTION(draw_handle) (cr, colors, &params, &handle, x, y, width, height);
+	}
+	else if (DETAIL ("paned"))
+	{
+		WidgetParameters params;
+		HandleParameters handle;
+
+		handle.type = MRN_HANDLE_SPLITTER;
+		handle.horizontal = orientation == GTK_ORIENTATION_HORIZONTAL;
+
+		murrine_set_widget_parameters (widget, style, state_type, &params);
+
+		STYLE_FUNCTION(draw_handle) (cr, colors, &params, &handle, x, y, width, height);
+	}
+	else
+	{
+		WidgetParameters params;
+		HandleParameters handle;
+
+		handle.type = MRN_HANDLE_TOOLBAR;
+		handle.horizontal = is_horizontal;
+
+		murrine_set_widget_parameters (widget, style, state_type, &params);
+
+		if (MRN_IS_TOOLBAR (widget) && shadow_type != GTK_SHADOW_NONE)
+		{
+			ToolbarParameters toolbar;
+
+			murrine_set_toolbar_parameters (&toolbar, widget, window, x, y);
+			toolbar.style = murrine_style->toolbarstyle;
+
+			cairo_save (cr);
+			STYLE_FUNCTION(draw_toolbar) (cr, colors, &params, &toolbar, x, y, width, height);
+			cairo_restore (cr);
+		}
+
+		STYLE_FUNCTION(draw_handle) (cr, colors, &params, &handle, x, y, width, height);
+	}
+
+	cairo_destroy (cr);
+}
+
+static void
+murrine_style_draw_box (DRAW_ARGS)
+{
+	MurrineStyle *murrine_style = MURRINE_STYLE (style);
+	const MurrineColors *colors = &murrine_style->colors;
+	cairo_t *cr;
+
+	CHECK_ARGS
+	SANITIZE_SIZE
+
+	cr = murrine_begin_paint (window, area);
+
+	if ((width == -1) && (height == -1))
+		gdk_window_get_size (window, &width, &height);
+	else if (width == -1)
+		gdk_window_get_size (window, &width, NULL);
+	else if (height == -1)
+		gdk_window_get_size (window, NULL, &height);
+
+	if (DETAIL ("menubar") &&
+	    !(widget && (murrine_is_panel_widget (widget->parent))))
+	{
+		WidgetParameters params;
+
+		murrine_set_widget_parameters (widget, style, state_type, &params);
+
+		if (params.mrn_gradient.use_rgba)
+		{
+			params.mrn_gradient.rgba_opacity = MENUBAR_GLOSSY_OPACITY;
+		}
+
+		STYLE_FUNCTION(draw_menubar) (cr, colors, &params, x, y, width, height,
+		                              murrine_style->menubarstyle);
+	}
+	else if (DETAIL ("button") && widget && widget->parent &&
+	                 (MRN_IS_TREE_VIEW(widget->parent) ||
+	                  MRN_IS_CLIST (widget->parent)))
+	{
+		WidgetParameters params;
+		ListViewHeaderParameters header;
+		header.style = murrine_style->listviewheaderstyle;
+
+		gint columns, column_index;
+		gboolean resizable = TRUE;
+
+		murrine_set_widget_parameters (widget, style, state_type, &params);
+		params.corners = MRN_CORNER_NONE;
+
+		if (MRN_IS_TREE_VIEW (widget->parent))
+		{
+			murrine_gtk_treeview_get_header_index (GTK_TREE_VIEW(widget->parent),
+			                                       widget, &column_index, &columns,
+			                                       &resizable);
+		}
+		else if (MRN_IS_CLIST (widget->parent))
+		{
+			murrine_gtk_clist_get_header_index (GTK_CLIST(widget->parent),
+			                                    widget, &column_index, &columns);
+		}
+
+		header.resizable = resizable;
+
+		if (column_index == 0)
+			header.order = params.ltr ? MRN_ORDER_FIRST : MRN_ORDER_LAST;
+		else if (column_index == columns-1)
+			header.order = params.ltr ? MRN_ORDER_LAST : MRN_ORDER_FIRST;
+		else
+			header.order = MRN_ORDER_MIDDLE;
+
+		gtk_style_apply_default_background (style, window, FALSE, state_type, area, x, y, width, height);
+
+		STYLE_FUNCTION(draw_list_view_header) (cr, colors, &params, &header, x, y, width, height);
+	}
+	else if (DETAIL ("button") || DETAIL ("buttondefault"))
+	{
+		WidgetParameters params;
+
+		murrine_set_widget_parameters (widget, style, state_type, &params);
+		params.roundness = murrine_style->roundness;
+
+		boolean horizontal = TRUE;
+		if (((float)width/height<0.5)|| (murrine_style->glazestyle > 0 && width<height))
+			horizontal = FALSE;
+
+		if ((widget && (MRN_IS_COMBO_BOX_ENTRY (widget->parent) || MRN_IS_COMBO (widget->parent))))
+		{
+			if (murrine_style->roundness > 0)
+			{
+				if (params.ltr)
+				{
+					params.corners = MRN_CORNER_TOPRIGHT | MRN_CORNER_BOTTOMRIGHT;
+					if (!horizontal)
+						params.corners = MRN_CORNER_BOTTOMLEFT | MRN_CORNER_BOTTOMRIGHT;
+				}
+				else
+				{
+					params.corners = MRN_CORNER_TOPLEFT | MRN_CORNER_BOTTOMLEFT;
+					if (!horizontal)
+						params.corners = MRN_CORNER_BOTTOMRIGHT | MRN_CORNER_BOTTOMLEFT;
+				}
+			}
+			else
+				params.corners = MRN_CORNER_NONE;
+
+			/* Seriously, why can't non-gtk-apps at least try to be decent citizens?
+			   Take this fucking OpenOffice.org 1.9 for example. The morons responsible
+			   for this utter piece of crap gave the clip size wrong values! :'(  */
+/*			cairo_reset_clip (cr);
+			cairo_rectangle (cr, x+ 0.5, y+ 0.5, 10, 10);
+			cairo_clip (cr);
+			cairo_new_path (cr);
+*/
+			if (params.xthickness > 1)
+			{
+				if (params.ltr)
+					x--;
+				width++;
+			}
+		}
+		else
+			if (murrine_style->roundness > 0)
+				params.corners = MRN_CORNER_ALL;
+			else
+				params.corners = MRN_CORNER_NONE;
+
+		if (MRN_IS_TOGGLE_BUTTON (widget) &&
+		    gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget)))
+			params.active = TRUE;
+
+		/* Fix some firefox crap. */
+		if (MRN_IS_BUTTON (widget) && MRN_IS_FIXED (widget->parent) && widget->allocation.x == -1 &&  widget->allocation.y == -1)
+		{
+			gtk_style_apply_default_background (widget->parent->style, window, TRUE, GTK_STATE_NORMAL,
+			                                    area, x, y, width, height);
+		}
+
+			STYLE_FUNCTION(draw_button) (cr, &murrine_style->colors, &params, x, y, width, height, horizontal);
+	}
+	else if (DETAIL ("spinbutton_up") || DETAIL ("spinbutton_down"))
+	{
+		if (state_type == GTK_STATE_ACTIVE)
+		{
+			WidgetParameters params;
+			murrine_set_widget_parameters (widget, style, state_type, &params);
+
+			if (style->xthickness > 1)
+			{
+				width++;
+				if (params.ltr)
+					x--;
+			}
+
+			if (DETAIL ("spinbutton_up"))
+			{
+				height+=2;
+				if (params.ltr)
+					params.corners = MRN_CORNER_TOPRIGHT;
+				else
+					params.corners = MRN_CORNER_TOPLEFT;
+			}
+			else
+			{
+				if (params.ltr)
+					params.corners = MRN_CORNER_BOTTOMRIGHT;
+				else
+					params.corners = MRN_CORNER_BOTTOMLEFT;
+			}
+
+			STYLE_FUNCTION(draw_spinbutton_down) (cr, &murrine_style->colors, &params, x, y, width, height);
+		}
+	}
+	else if (DETAIL ("spinbutton"))
+	{
+		WidgetParameters params;
+
+		murrine_set_widget_parameters (widget, style, state_type, &params);
+		params.roundness = murrine_style->roundness;
+
+		boolean horizontal = TRUE;
+		if (((float)width/height<0.5)|| (murrine_style->glazestyle > 0 && width<height))
+			horizontal = FALSE;
+
+		if (murrine_style->roundness > 0)
+		{
+			if (params.ltr)
+			{
+				params.corners = MRN_CORNER_TOPRIGHT | MRN_CORNER_BOTTOMRIGHT;
+				if (!horizontal)
+					params.corners = MRN_CORNER_BOTTOMLEFT | MRN_CORNER_BOTTOMRIGHT;
+			}
+			else
+			{
+				params.corners = MRN_CORNER_TOPLEFT | MRN_CORNER_BOTTOMLEFT;
+				if (!horizontal)
+					params.corners = MRN_CORNER_BOTTOMRIGHT | MRN_CORNER_BOTTOMLEFT;
+			}
+		}
+		else
+			params.corners = MRN_CORNER_NONE;
+
+		if (style->xthickness > 1)
+		{
+			if (params.ltr)
+				x--;
+			width++;
+		}
+
+		/* draw_spinbutton (cr, &murrine_style->colors, &params, x, y, width, height); */
+		STYLE_FUNCTION(draw_button) (cr, &murrine_style->colors, &params, x, y, width, height, horizontal);
+	}
+	else if (DETAIL ("trough") && widget && MRN_IS_SCALE (widget))
+	{
+		GtkAdjustment *adjustment = gtk_range_get_adjustment (GTK_RANGE (widget));
+		WidgetParameters params;
+		SliderParameters slider;
+		gint slider_length;
+
+		gtk_widget_style_get (widget, "slider-length", &slider_length, NULL);
+
+		slider.inverted   = gtk_range_get_inverted (GTK_RANGE (widget));
+		slider.horizontal = (GTK_RANGE (widget)->orientation == GTK_ORIENTATION_HORIZONTAL);
+		slider.fill_size  = ((slider.horizontal ? width : height) - slider_length) *
+		                     (1 / ((adjustment->upper - adjustment->lower) / (adjustment->value - adjustment->lower)))
+		                     + slider_length / 2;
+		if (slider.horizontal)
+			slider.inverted = slider.inverted != (murrine_get_direction (widget) == GTK_TEXT_DIR_RTL);
+
+		murrine_set_widget_parameters (widget, style, state_type, &params);
+		params.corners    = MRN_CORNER_NONE;
+
+		STYLE_FUNCTION(draw_scale_trough) (cr, &murrine_style->colors,
+		                                   &params, &slider,
+		                                   x, y, width, height);
+	}
+	else if (DETAIL ("trough") && widget && MRN_IS_PROGRESS_BAR (widget))
+	{
+		WidgetParameters params;
+
+		murrine_set_widget_parameters (widget, style, state_type, &params);
+
+		STYLE_FUNCTION(draw_progressbar_trough) (cr, colors, &params, x, y, width, height);
+	}
+	else if (DETAIL ("trough") && widget && (MRN_IS_VSCROLLBAR (widget) || MRN_IS_HSCROLLBAR (widget)))
+	{
+		WidgetParameters params;
+		ScrollBarParameters scrollbar;
+
+		scrollbar.horizontal   = TRUE;
+		scrollbar.junction     = murrine_scrollbar_get_junction (widget);
+		scrollbar.steppers     = murrine_scrollbar_visible_steppers (widget);
+		scrollbar.stepperstyle = murrine_style->stepperstyle;
+
+		murrine_set_widget_parameters (widget, style, state_type, &params);
+
+		if (murrine_style->roundness > 0)
+			params.corners = MRN_CORNER_ALL;
+		else
+			params.corners = MRN_CORNER_NONE;
+
+		if (MRN_IS_RANGE (widget))
+			scrollbar.horizontal = GTK_RANGE (widget)->orientation == GTK_ORIENTATION_HORIZONTAL;
+
+		if (murrine_style->stepperstyle != 1 && !params.mrn_gradient.use_rgba)
+		{
+			if (scrollbar.horizontal)
+			{
+				x += 2;
+				width -= 4;
+			}
+			else
+			{
+				y += 2;
+				height -= 4;
+			}
+		}
+
+		STYLE_FUNCTION(draw_scrollbar_trough) (cr, colors, &params, &scrollbar, x, y, width, height);
+	}
+	else if (DETAIL ("bar"))
+	{
+		WidgetParameters      params;
+
+		ProgressBarParameters progressbar;
+		gdouble               elapsed = 0.0;
+
+		if (widget && MRN_IS_PROGRESS_BAR (widget))
+			progressbar.orientation = gtk_progress_bar_get_orientation (GTK_PROGRESS_BAR (widget));
+		else
+			progressbar.orientation = MRN_ORIENTATION_LEFT_TO_RIGHT;
+
+		if (!params.ltr)
+		{
+			if (progressbar.orientation == GTK_PROGRESS_LEFT_TO_RIGHT)
+				progressbar.orientation = GTK_PROGRESS_RIGHT_TO_LEFT;
+			else if (progressbar.orientation == GTK_PROGRESS_RIGHT_TO_LEFT)
+				progressbar.orientation = GTK_PROGRESS_LEFT_TO_RIGHT;
+		}
+
+#ifdef HAVE_ANIMATION
+		if(murrine_style->animation && MRN_IS_PROGRESS_BAR (widget))
+		{
+			gboolean activity_mode = GTK_PROGRESS (widget)->activity_mode;
+
+			if (!activity_mode)
+				murrine_animation_progressbar_add ((gpointer)widget);
+		}
+
+		elapsed = murrine_animation_elapsed (widget);
+#endif
+
+		murrine_set_widget_parameters (widget, style, state_type, &params);
+		params.roundness = murrine_style->roundness;
+
+		/* cairo_reset_clip (cr); */
+
+		/* The x-1 and width+2 are to make the fill cover the left and
+		 * right-hand sides of the trough box */
+
+#ifndef HAVE_ANIMATIONTOLEFT
+		STYLE_FUNCTION(draw_progressbar_fill) (cr, colors, &params, &progressbar,
+		                                       x-1, y, width+2, height,
+		                                       10 - (int)(elapsed * 10.0) % 10);
+#else
+		STYLE_FUNCTION(draw_progressbar_fill) (cr, colors, &params, &progressbar,
+		                                       x-1, y, width+2, height,
+		                                       10 + (int)(elapsed * 10.0) % 10);
+#endif
+	}
+	else if (DETAIL ("hscale") || DETAIL ("vscale"))
+	{
+		WidgetParameters params;
+		/* SliderParameters slider; */
+
+		murrine_set_widget_parameters (widget, style, state_type, &params);
+
+		boolean horizontal = TRUE;
+		if (DETAIL ("vscale"))
+			horizontal = FALSE;
+
+		if (murrine_style->roundness > 0)
+			params.corners = MRN_CORNER_ALL;
+		else
+			params.corners = MRN_CORNER_NONE;
+
+		STYLE_FUNCTION(draw_button) (cr, &murrine_style->colors, &params, x, y, width, height, horizontal);
+
+		if (murrine_style->sliderstyle == 1)
+			STYLE_FUNCTION(draw_slider_handle) (cr, &murrine_style->colors, &params, x, y, width, height, horizontal);
+	}
+	else if (DETAIL ("optionmenu"))
+	{
+		WidgetParameters params;
+		OptionMenuParameters optionmenu;
+
+		GtkRequisition indicator_size;
+		GtkBorder indicator_spacing;
+
+		murrine_option_menu_get_props (widget, &indicator_size, &indicator_spacing);
+
+		if (widget && murrine_get_direction (widget) == GTK_TEXT_DIR_RTL)
+			optionmenu.linepos = (indicator_size.width + indicator_spacing.left + indicator_spacing.right) + style->xthickness;
+		else
+			optionmenu.linepos = width - (indicator_size.width + indicator_spacing.left + indicator_spacing.right) - style->xthickness;
+
+		murrine_set_widget_parameters (widget, style, state_type, &params);
+
+		if (murrine_style->roundness > 0)
+			params.corners = MRN_CORNER_ALL;
+		else
+			params.corners = MRN_CORNER_NONE;
+
+		STYLE_FUNCTION(draw_optionmenu) (cr, colors, &params, &optionmenu, x, y, width, height);
+	}
+	else if (DETAIL ("menuitem"))
+	{
+		WidgetParameters params;
+
+		murrine_set_widget_parameters (widget, style, state_type, &params);
+
+		if (murrine_style->roundness > 0)
+			params.corners = MRN_CORNER_ALL;
+		else
+			params.corners = MRN_CORNER_NONE;
+
+		if (widget && !(MRN_IS_MENU_BAR (widget->parent) && murrine_style->menubaritemstyle))
+		{
+			if (murrine_style->menustyle != 1 || (MRN_IS_MENU_BAR (widget->parent) && !murrine_style->menubaritemstyle))
+				STYLE_FUNCTION(draw_menuitem) (cr, colors, &params, x, y, width, height, murrine_style->menuitemstyle);
+			else
+				/* little translation */
+				STYLE_FUNCTION(draw_menuitem) (cr, colors, &params, x+3, y, width-3, height, murrine_style->menuitemstyle);
+		}
+
+		if (widget && MRN_IS_MENU_BAR (widget->parent) && murrine_style->menubaritemstyle)
+		{
+			params.active = FALSE;
+			params.prelight = TRUE;
+			params.focus = TRUE;
+			params.state_type = MRN_STATE_SELECTED;
+			params.xthickness = 2;
+			params.ythickness = 2;
+
+			if (murrine_style->roundness > 0)
+				params.corners = MRN_CORNER_TOPRIGHT | MRN_CORNER_TOPLEFT;
+			else
+				params.corners = MRN_CORNER_NONE;
+
+				STYLE_FUNCTION(draw_button) (cr, colors, &params, x, y, width, height+1, TRUE);
+		}
+	}
+	else if (DETAIL ("hscrollbar") || DETAIL ("vscrollbar") || DETAIL ("slider") || DETAIL ("stepper"))
+	{
+		WidgetParameters    params;
+		ScrollBarParameters scrollbar;
+
+		scrollbar.has_color    = FALSE;
+		scrollbar.horizontal   = TRUE;
+		scrollbar.junction     = murrine_scrollbar_get_junction (widget);
+		scrollbar.steppers     = murrine_scrollbar_visible_steppers (widget);
+		scrollbar.style        = murrine_style->scrollbarstyle;
+		scrollbar.stepperstyle = murrine_style->stepperstyle;
+
+		if (MRN_IS_RANGE (widget))
+			scrollbar.horizontal = GTK_RANGE (widget)->orientation == GTK_ORIENTATION_HORIZONTAL;
+
+		if (murrine_style->colorize_scrollbar)
+		{
+			scrollbar.color = colors->spot[1];
+			scrollbar.has_color = TRUE;
+		}
+
+		if (!scrollbar.has_color)
+			scrollbar.color = colors->bg[0];
+
+		if (murrine_style->has_scrollbar_color)
+		{
+			murrine_gdk_color_to_rgb (&murrine_style->scrollbar_color, &scrollbar.color.r, &scrollbar.color.g, &scrollbar.color.b);
+			scrollbar.has_color = TRUE;
+		}
+
+		murrine_set_widget_parameters (widget, style, state_type, &params);
+
+		params.corners = MRN_CORNER_NONE;
+
+		if (DETAIL ("slider"))
+		{
+			if (murrine_style->roundness == 1)
+				params.corners = MRN_CORNER_ALL;
+			else
+				params.corners = MRN_CORNER_NONE;
+
+			STYLE_FUNCTION(draw_scrollbar_slider) (cr, colors, &params, &scrollbar, x, y, width, height);
+		}
+		else
+		{
+			if (murrine_style->roundness > 1)
+			{
+				ScrollBarStepperParameters stepper;
+				GdkRectangle this_rectangle = { x, y, width, height };
+
+				stepper.stepper = murrine_scrollbar_get_stepper (widget, &this_rectangle);
+
+				if (scrollbar.horizontal)
+				{
+					if (stepper.stepper == MRN_STEPPER_A)
+						params.corners = MRN_CORNER_TOPLEFT | MRN_CORNER_BOTTOMLEFT;
+					else if (stepper.stepper == MRN_STEPPER_D)
+						params.corners = MRN_CORNER_TOPRIGHT | MRN_CORNER_BOTTOMRIGHT;
+				}
+				else
+				{
+					if (stepper.stepper == MRN_STEPPER_A)
+						params.corners = MRN_CORNER_BOTTOMLEFT | MRN_CORNER_TOPLEFT;
+					else if (stepper.stepper == MRN_STEPPER_D)
+						params.corners = MRN_CORNER_TOPRIGHT | MRN_CORNER_BOTTOMRIGHT;
+				}
+			}
+			else if (murrine_style->roundness == 1)
+				params.corners = MRN_CORNER_ALL;
+			else
+				params.corners = MRN_CORNER_NONE;
+
+			if (murrine_style->stepperstyle != 1)
+				STYLE_FUNCTION(draw_scrollbar_stepper) (cr, colors, &params, &scrollbar, x, y, width, height);
+		}
+	}
+	else if (DETAIL ("toolbar") || DETAIL ("handlebox_bin") || DETAIL ("dockitem_bin"))
+	{
+		/* Only draw the shadows on horizontal toolbars */
+		if (shadow_type != GTK_SHADOW_NONE && height < 2*width )
+		{
+			WidgetParameters params;
+			ToolbarParameters toolbar;
+
+			murrine_set_widget_parameters (widget, style, state_type, &params);
+
+			murrine_set_toolbar_parameters (&toolbar, widget, window, x, y);
+			toolbar.style = murrine_style->toolbarstyle;
+
+			STYLE_FUNCTION(draw_toolbar) (cr, colors, &params, &toolbar, x, y, width, height);
+		}
+	}
+	else if (DETAIL ("trough"))
+	{
+		/* Do nothing? */
+	}
+	else if (DETAIL ("menu"))
+	{
+		WidgetParameters params;
+
+		murrine_set_widget_parameters (widget, style, state_type, &params);
+
+		STYLE_FUNCTION(draw_menu_frame) (cr, colors, &params, x, y, width, height, murrine_style->menustyle);
+	}
+	else
+	{
+		murrine_parent_class->draw_box (style, window, state_type, shadow_type, area,
+		                                widget, detail, x, y, width, height);
+	}
+
+	cairo_destroy (cr);
+}
+
+static void
+murrine_style_draw_slider (DRAW_ARGS, GtkOrientation orientation)
+{
+	if (DETAIL ("hscale") || DETAIL ("vscale"))
+	{
+		murrine_style_draw_box (style, window, state_type, shadow_type, area,
+		                        widget, detail, x, y, width, height);
+	}
+	else
+		murrine_parent_class->draw_slider (style, window, state_type, shadow_type, area,
+		                                   widget, detail, x, y, width, height, orientation);
+}
+
+static void
+murrine_style_draw_option (DRAW_ARGS)
+{
+	MurrineStyle *murrine_style = MURRINE_STYLE (style);
+	MurrineColors *colors = &murrine_style->colors;
+	cairo_t *cr;
+
+	CHECK_ARGS
+	SANITIZE_SIZE
+
+	cr = murrine_begin_paint (window, area);
+
+	WidgetParameters params;
+	OptionParameters option;
+
+	option.draw_bullet = ((shadow_type == GTK_SHADOW_IN) || (shadow_type == GTK_SHADOW_ETCHED_IN));
+	option.inconsistent = (shadow_type == GTK_SHADOW_ETCHED_IN);
+	double trans = 1.0;
+
+	murrine_set_widget_parameters (widget, style, state_type, &params);
+
+	#ifdef HAVE_ANIMATION
+		if (murrine_style->animation)
+			murrine_animation_connect_checkbox (widget);
+
+		if (murrine_style->animation &&
+		    MRN_IS_CHECK_BUTTON (widget) &&
+		    murrine_animation_is_animated (widget) &&
+		    !gtk_toggle_button_get_inconsistent (GTK_TOGGLE_BUTTON (widget)))
+		{
+			gfloat elapsed = murrine_animation_elapsed (widget);
+			trans = sqrt (sqrt (MIN(elapsed / CHECK_ANIMATION_TIME, 1.0)));
+		}
+	#endif
+
+	STYLE_FUNCTION(draw_radiobutton) (cr, colors, &params, &option, x, y, width, height, trans);
+
+	cairo_destroy (cr);
+}
+
+static void
+murrine_style_draw_check (DRAW_ARGS)
+{
+	MurrineStyle *murrine_style = MURRINE_STYLE (style);
+	MurrineColors *colors = &murrine_style->colors;
+	cairo_t *cr;
+
+	CHECK_ARGS
+	SANITIZE_SIZE
+
+	cr = murrine_begin_paint (window, area);
+
+	WidgetParameters params;
+	OptionParameters option;
+
+	option.draw_bullet = ((shadow_type == GTK_SHADOW_IN) || (shadow_type == GTK_SHADOW_ETCHED_IN));
+	option.inconsistent = (shadow_type == GTK_SHADOW_ETCHED_IN);
+	double trans = 1.0;
+
+	murrine_set_widget_parameters (widget, style, state_type, &params);
+
+	#ifdef HAVE_ANIMATION
+		if (murrine_style->animation)
+			murrine_animation_connect_checkbox (widget);
+
+		if (murrine_style->animation && MRN_IS_CHECK_BUTTON (widget) &&
+		    murrine_animation_is_animated (widget) &&
+		    !gtk_toggle_button_get_inconsistent (GTK_TOGGLE_BUTTON (widget)))
+		{
+			gfloat elapsed = murrine_animation_elapsed (widget);
+			trans = sqrt (sqrt (MIN(elapsed / CHECK_ANIMATION_TIME, 1.0)));
+		}
+	#endif
+
+	STYLE_FUNCTION(draw_checkbox) (cr, colors, &params, &option, x, y, width, height, trans);
+
+	cairo_destroy (cr);
+}
+
+static void
+murrine_style_draw_tab (DRAW_ARGS)
+{
+	MurrineStyle *murrine_style = MURRINE_STYLE (style);
+	MurrineColors *colors = &murrine_style->colors;
+
+	cairo_t *cr;
+
+	CHECK_ARGS
+	SANITIZE_SIZE
+
+	cr = murrine_begin_paint (window, area);
+
+	WidgetParameters params;
+	ArrowParameters  arrow;
+
+	arrow.type      = MRN_ARROW_COMBO;
+	arrow.direction = MRN_DIRECTION_DOWN;
+
+	murrine_set_widget_parameters (widget, style, state_type, &params);
+
+	STYLE_FUNCTION(draw_arrow) (cr, colors, &params, &arrow, x, y, width, height);
+
+	cairo_destroy (cr);
+}
+
+static void
+murrine_style_draw_vline (GtkStyle     *style,
+                          GdkWindow    *window,
+                          GtkStateType  state_type,
+                          GdkRectangle *area,
+                          GtkWidget    *widget,
+                          const gchar  *detail,
+                          gint          y1,
+                          gint          y2,
+                          gint          x)
+{
+	/* Get toplevel window for this widget */
+	GtkWidget* toplevel = gtk_widget_get_toplevel (widget);
+
+	MurrineStyle  *murrine_style = MURRINE_STYLE (style);
+	MurrineColors *colors = &murrine_style->colors;
+	cairo_t *cr;
+
+	CHECK_ARGS
+
+	cr = murrine_begin_paint (window, area);
+
+	SeparatorParameters separator;
+	separator.horizontal = FALSE;
+
+	WidgetParameters params;
+
+	params.drawstyle = MRN_DRAW_STYLE_MURRINE;
+	if (murrine_widget_is_rgba (toplevel))
+	{
+		params.drawstyle = MRN_DRAW_STYLE_RGBA;
+	}
+
+	if (!(widget &&
+	    MRN_IS_HBOX (widget->parent) &&
+	    MRN_IS_TOGGLE_BUTTON (widget->parent->parent) &&
+	    MRN_IS_COMBO_BOX (widget->parent->parent->parent)))
+	{
+		STYLE_FUNCTION(draw_separator) (cr, colors, NULL, &separator, x, y1, 2, y2-y1);
+	}
+	else
+		STYLE_FUNCTION(draw_combo_separator) (cr, colors, NULL, x, y1, 2, y2-y1);
+
+	cairo_destroy (cr);
+}
+
+static void
+murrine_style_draw_hline (GtkStyle     *style,
+                          GdkWindow    *window,
+                          GtkStateType  state_type,
+                          GdkRectangle *area,
+                          GtkWidget    *widget,
+                          const gchar  *detail,
+                          gint          x1,
+                          gint          x2,
+                          gint          y)
+{
+	/* Get toplevel window for this widget */
+	GtkWidget* toplevel = gtk_widget_get_toplevel (widget);
+
+	MurrineStyle *murrine_style = MURRINE_STYLE (style);
+	MurrineColors *colors = &murrine_style->colors;
+	cairo_t *cr;
+
+	CHECK_ARGS
+
+	cr = murrine_begin_paint (window, area);
+
+	SeparatorParameters separator;
+	separator.horizontal = TRUE;
+
+	WidgetParameters params;
+
+	params.drawstyle = MRN_DRAW_STYLE_MURRINE;
+	if (murrine_widget_is_rgba (toplevel))
+	{
+		params.drawstyle = MRN_DRAW_STYLE_RGBA;
+	}
+
+	STYLE_FUNCTION(draw_separator) (cr, colors, NULL, &separator, x1, y, x2-x1, 2);
+
+	cairo_destroy (cr);
+}
+
+static void
+murrine_style_draw_shadow_gap (DRAW_ARGS,
+                               GtkPositionType gap_side,
+                               gint            gap_x,
+                               gint            gap_width)
+{
+	MurrineStyle *murrine_style = MURRINE_STYLE (style);
+	const MurrineColors *colors = &murrine_style->colors;
+	cairo_t *cr;
+
+	CHECK_ARGS
+	SANITIZE_SIZE
+
+	cr = murrine_begin_paint (window, area);
+
+	if (DETAIL ("frame"))
+	{
+		WidgetParameters params;
+		FrameParameters  frame;
+
+		frame.shadow    = shadow_type;
+		frame.gap_side  = gap_side;
+		frame.gap_x     = gap_x;
+		frame.gap_width = gap_width;
+		frame.border    = (MurrineRGB*)&colors->shade[4];
+
+		murrine_set_widget_parameters (widget, style, state_type, &params);
+
+		params.corners = MRN_CORNER_ALL;
+
+		if (params.roundness < 2)
+			params.corners = MRN_CORNER_NONE;
+
+		STYLE_FUNCTION(draw_frame) (cr, colors, &params, &frame, x, y, width, height);
+	}
+	else
+	{
+		murrine_parent_class->draw_shadow_gap (style, window, state_type, shadow_type, area,
+		                                       widget, detail, x, y, width, height,
+		                                       gap_side, gap_x, gap_width);
+	}
+
+	cairo_destroy (cr);
+}
+
+static void
+murrine_style_draw_resize_grip (GtkStyle      *style,
+                                GdkWindow     *window,
+                                GtkStateType  state_type,
+                                GdkRectangle  *area,
+                                GtkWidget     *widget,
+                                const gchar   *detail,
+                                GdkWindowEdge edge,
+                                gint          x,
+                                gint          y,
+                                gint          width,
+                                gint          height)
+{
+	MurrineStyle *murrine_style = MURRINE_STYLE (style);
+	MurrineColors *colors = &murrine_style->colors;
+
+	cairo_t *cr;
+
+	CHECK_ARGS
+	SANITIZE_SIZE
+
+	cr = murrine_begin_paint (window, area);
+
+	WidgetParameters params;
+	ResizeGripParameters grip;
+	grip.edge = (MurrineWindowEdge)edge;
+
+	int lx, ly;
+
+	g_return_if_fail (window != NULL);
+
+	if (edge != GDK_WINDOW_EDGE_SOUTH_EAST)
+		return; /* sorry... need to work on this :P */
+
+	murrine_set_widget_parameters (widget, style, state_type, &params);
+
+	STYLE_FUNCTION(draw_resize_grip) (cr, colors, &params, &grip, x, y, width, height);
+
+	cairo_destroy (cr);
+
+	return;
+}
+
+static void
+murrine_style_draw_arrow (GtkStyle     *style,
+                          GdkWindow    *window,
+                          GtkStateType  state_type,
+                          GtkShadowType shadow,
+                          GdkRectangle  *area,
+                          GtkWidget     *widget,
+                          const gchar   *detail,
+                          GtkArrowType  arrow_type,
+                          gboolean      fill,
+                          gint          x,
+                          gint          y,
+                          gint          width,
+                          gint          height)
+{
+	MurrineStyle  *murrine_style = MURRINE_STYLE (style);
+	MurrineColors *colors = &murrine_style->colors;
+	cairo_t *cr;
+
+	CHECK_ARGS
+	SANITIZE_SIZE;
+
+	cr = murrine_begin_paint (window, area);
+
+	WidgetParameters params;
+	ArrowParameters  arrow;
+
+	if (arrow_type == GTK_ARROW_NONE)
+	{
+		cairo_destroy (cr);
+		return;
+	}
+
+	arrow.type = MRN_ARROW_NORMAL;
+	arrow.direction = (MurrineDirection)arrow_type;
+
+	if (MRN_IS_COMBO_BOX (widget) && !MRN_IS_COMBO_BOX_ENTRY (widget))
+	{
+		arrow.type = MRN_ARROW_COMBO;
+	}
+
+	murrine_set_widget_parameters (widget, style, state_type, &params);
+
+	/* I have no idea why, but the arrow of GtkCombo is larger than in other places.
+	 * Subtracting 3 seems to fix this. */
+	if (widget && widget->parent && MRN_IS_COMBO (widget->parent->parent))
+	{
+		if (params.ltr)
+			x += 1;
+		else
+			x += 2;
+		width -= 3;
+	}
+
+	STYLE_FUNCTION(draw_arrow) (cr, colors, &params, &arrow, x, y, width, height);
+
+	cairo_destroy (cr);
+}
+
+static void
+murrine_style_draw_layout (GtkStyle     *style,
+                           GdkWindow    *window,
+                           GtkStateType state_type,
+                           gboolean     use_text,
+                           GdkRectangle *area,
+                           GtkWidget    *widget,
+                           const gchar  *detail, gint x, gint y,
+                           PangoLayout  *layout)
+{
+	GdkGC *gc;
+
+	g_return_if_fail (GTK_IS_STYLE (style));
+	g_return_if_fail (window != NULL);
+
+	gc = use_text ? style->text_gc[state_type] : style->fg_gc[state_type];
+
+	if (area)
+		gdk_gc_set_clip_rectangle (gc, area);
+
+	if (state_type == GTK_STATE_INSENSITIVE)
+	{
+		MurrineStyle *murrine_style = MURRINE_STYLE (style);
+		MurrineColors *colors = &murrine_style->colors;
+
+		WidgetParameters params;
+
+		murrine_set_widget_parameters (widget, style, state_type, &params);
+
+		GdkColor etched;
+		MurrineRGB temp;
+
+		if (GTK_WIDGET_NO_WINDOW (widget))
+			murrine_shade (&params.parentbg, &temp, 1.2);
+		else
+			murrine_shade (&colors->bg[widget->state], &temp, 1.2);
+
+		etched.red = (int) (temp.r * 65535);
+		etched.green = (int) (temp.g * 65535);
+		etched.blue = (int) (temp.b * 65535);
+
+		gdk_draw_layout_with_colors (window, gc, x + 1, y + 1, layout, &etched, NULL);
+		gdk_draw_layout (window, gc, x, y, layout);
+	}
+	else
+	{
+		gdk_draw_layout (window, gc, x, y, layout);
+	}
+
+	if (area)
+		gdk_gc_set_clip_rectangle (gc, NULL);
+}
+
+static void
+murrine_style_init_from_rc (GtkStyle   *style,
+                            GtkRcStyle *rc_style)
+{
+	MurrineStyle *murrine_style = MURRINE_STYLE (style);
+
+	murrine_parent_class->init_from_rc (style, rc_style);
+
+	murrine_style->gradient_stop_1    = MURRINE_RC_STYLE (rc_style)->gradient_stop_1;
+	murrine_style->gradient_stop_2    = MURRINE_RC_STYLE (rc_style)->gradient_stop_2;
+	murrine_style->gradient_stop_3    = MURRINE_RC_STYLE (rc_style)->gradient_stop_3;
+	murrine_style->gradient_stop_4    = MURRINE_RC_STYLE (rc_style)->gradient_stop_4;
+	murrine_style->has_gradient_stop  = MURRINE_RC_STYLE (rc_style)->has_gradient_stop;
+	murrine_style->highlight_ratio    = MURRINE_RC_STYLE (rc_style)->highlight_ratio;
+	murrine_style->innerborder_ratio  = MURRINE_RC_STYLE (rc_style)->innerborder_ratio;
+	murrine_style->glazestyle         = MURRINE_RC_STYLE (rc_style)->glazestyle;
+
+	if (murrine_style->has_gradient_stop &&
+	    murrine_style->glazestyle != 0)
+	{
+		double gradient_stop_mid = ((murrine_style->gradient_stop_2)+(murrine_style->gradient_stop_2))/2.0;
+		murrine_style->gradient_stop_2 = gradient_stop_mid;
+		murrine_style->gradient_stop_3 = gradient_stop_mid;
+	}
+
+	/* Ignore roundness > 1 with glazestyle = 2 */
+	if (murrine_style->glazestyle == 2)
+	{
+		if (MURRINE_RC_STYLE (rc_style)->roundness > 0)
+			murrine_style->roundness = 1;
+		else
+			murrine_style->roundness = 0;
+	}
+	else
+		murrine_style->roundness       = MURRINE_RC_STYLE (rc_style)->roundness;
+	murrine_style->menubarstyle        = MURRINE_RC_STYLE (rc_style)->menubarstyle;
+	murrine_style->menubaritemstyle    = MURRINE_RC_STYLE (rc_style)->menubaritemstyle;
+	murrine_style->menustyle           = MURRINE_RC_STYLE (rc_style)->menustyle;
+	murrine_style->menuitemstyle       = MURRINE_RC_STYLE (rc_style)->menuitemstyle;
+	murrine_style->listviewheaderstyle = MURRINE_RC_STYLE (rc_style)->listviewheaderstyle;
+	murrine_style->listviewstyle       = MURRINE_RC_STYLE (rc_style)->listviewstyle;
+	murrine_style->sliderstyle         = MURRINE_RC_STYLE (rc_style)->sliderstyle;
+	murrine_style->scrollbarstyle      = MURRINE_RC_STYLE (rc_style)->scrollbarstyle;
+	murrine_style->has_scrollbar_color = MURRINE_RC_STYLE (rc_style)->has_scrollbar_color;
+	murrine_style->stepperstyle        = MURRINE_RC_STYLE (rc_style)->stepperstyle;
+	murrine_style->toolbarstyle        = MURRINE_RC_STYLE (rc_style)->toolbarstyle;
+	murrine_style->animation           = MURRINE_RC_STYLE (rc_style)->animation;
+	murrine_style->gradients           = MURRINE_RC_STYLE (rc_style)->gradients;
+	murrine_style->colorize_scrollbar  = MURRINE_RC_STYLE (rc_style)->colorize_scrollbar;
+	murrine_style->rgba                = MURRINE_RC_STYLE (rc_style)->rgba;
+
+	if (murrine_style->has_scrollbar_color)
+		murrine_style->scrollbar_color = MURRINE_RC_STYLE (rc_style)->scrollbar_color;
+
+	g_assert ((MURRINE_RC_STYLE (rc_style)->style >= 0) && (MURRINE_RC_STYLE (rc_style)->style < MRN_NUM_STYLES));
+	murrine_style->style               = MURRINE_RC_STYLE (rc_style)->style;
+
+	switch (murrine_style->style)
+	{
+		case (MRN_STYLE_NODOKA):
+			murrine_style->highlight_ratio = 1.0;
+			murrine_style->gradients = TRUE;
+			murrine_style->sliderstyle = 1;
+			murrine_style->scrollbarstyle = 2;
+			murrine_style->stepperstyle = 0;
+			murrine_style->colorize_scrollbar = FALSE;
+			murrine_style->has_scrollbar_color = FALSE;
+			murrine_style->has_gradient_stop = FALSE;
+			break;
+		case (MRN_STYLE_MIST):
+			murrine_style->highlight_ratio = 1.0;
+			murrine_style->gradients = FALSE;
+			break;
+		case (MRN_STYLE_CANDIDO):
+			murrine_style->highlight_ratio = 1.0;
+			murrine_style->innerborder_ratio = 1.06;
+			murrine_style->gradients = TRUE;
+			murrine_style->gradient_stop_1 = 1.01;
+			murrine_style->gradient_stop_2 = 0.99;
+			murrine_style->gradient_stop_3 = 0.99;
+			murrine_style->gradient_stop_4 = 0.97;
+			break;
+		case (MRN_STYLE_CLEARLOOKS):
+			murrine_style->gradient_stop_1 = 1.08;
+			murrine_style->gradient_stop_2 = 1.02;
+			murrine_style->gradient_stop_3 = 1.00;
+			murrine_style->gradient_stop_4 = 0.94;
+			murrine_style->has_gradient_stop = TRUE;
+			murrine_style->gradients = TRUE;
+			murrine_style->highlight_ratio = 1.0;
+			murrine_style->toolbarstyle = 1;
+			murrine_style->innerborder_ratio = 1.02;
+			murrine_style->menustyle = 0;
+			murrine_style->sliderstyle = 1;
+			murrine_style->scrollbarstyle = 2;
+			break;
+	};
+}
+
+static void
+murrine_style_realize (GtkStyle * style)
+{
+	MurrineStyle *murrine_style = MURRINE_STYLE (style);
+	double shades[] = {1.15, 0.95, 0.896, 0.82, 0.75, 0.665, 0.5, 0.45, 0.4};
+	MurrineRGB spot_color;
+	MurrineRGB bg_normal;
+	double contrast;
+	int i;
+
+	murrine_parent_class->realize (style);
+
+	contrast = MURRINE_RC_STYLE (style->rc_style)->contrast;
+
+	bg_normal.r = style->bg[0].red   / 65535.0;
+	bg_normal.g = style->bg[0].green / 65535.0;
+	bg_normal.b = style->bg[0].blue  / 65535.0;
+
+	/* Lighter to darker */
+	for (i = 0; i < 9; i++)
+	{
+		murrine_shade (&bg_normal, &murrine_style->colors.shade[i],
+		               (shades[i]-0.9) * contrast + 0.9);
+	}
+
+	spot_color.r = style->bg[GTK_STATE_SELECTED].red   / 65535.0;
+	spot_color.g = style->bg[GTK_STATE_SELECTED].green / 65535.0;
+	spot_color.b = style->bg[GTK_STATE_SELECTED].blue  / 65535.0;
+
+	murrine_shade (&spot_color, &murrine_style->colors.spot[0], 1.42);
+	murrine_shade (&spot_color, &murrine_style->colors.spot[1], 1.00);
+	murrine_shade (&spot_color, &murrine_style->colors.spot[2], 0.65);
+
+	for (i=0; i<5; i++)
+	{
+		murrine_gdk_color_to_rgb (&style->bg[i],
+		                          &murrine_style->colors.bg[i].r,
+		                          &murrine_style->colors.bg[i].g,
+		                          &murrine_style->colors.bg[i].b);
+
+		murrine_gdk_color_to_rgb (&style->base[i],
+		                          &murrine_style->colors.base[i].r,
+		                          &murrine_style->colors.base[i].g,
+		                          &murrine_style->colors.base[i].b);
+
+		murrine_gdk_color_to_rgb (&style->text[i],
+		                          &murrine_style->colors.text[i].r,
+		                          &murrine_style->colors.text[i].g,
+		                          &murrine_style->colors.text[i].b);
+
+		murrine_gdk_color_to_rgb (&style->fg[i],
+		                          &murrine_style->colors.fg[i].r,
+		                          &murrine_style->colors.fg[i].g,
+		                          &murrine_style->colors.fg[i].b);
+	}
+}
+
+static void
+gdk_cairo_set_source_color_alpha (cairo_t  *cr,
+                                  GdkColor *color,
+                                  float    alpha)
+{
+	g_return_if_fail (cr != NULL);
+	g_return_if_fail (color != NULL);
+
+	cairo_set_source_rgba (cr,
+	                       color->red / 65535.,
+	                       color->green / 65535.,
+	                       color->blue / 65535.,
+	                       alpha);
+}
+
+static void
+murrine_style_draw_focus (GtkStyle *style, GdkWindow *window, GtkStateType state_type,
+                          GdkRectangle *area, GtkWidget *widget, const gchar *detail,
+                          gint x, gint y, gint width, gint height)
+{
+	cairo_t *cr;
+
+	CHECK_ARGS
+	SANITIZE_SIZE
+
+	cr = gdk_cairo_create (window);
+
+	gboolean free_dash_list = FALSE;
+	gint line_width = 1;
+	gint8 *dash_list = "\1\1";
+
+	if (widget)
+	{
+		gtk_widget_style_get (widget,
+		                     "focus-line-width", &line_width,
+		                     "focus-line-pattern",
+		                     (gchar *) & dash_list, NULL);
+
+		free_dash_list = TRUE;
+	}
+
+	if (detail && !strcmp (detail, "add-mode"))
+	{
+		if (free_dash_list)
+			g_free (dash_list);
+
+		dash_list = "\4\4";
+		free_dash_list = FALSE;
+	}
+
+	if (detail && !strcmp (detail, "colorwheel_light"))
+		cairo_set_source_rgb (cr, 0., 0., 0.);
+	else if (detail && !strcmp (detail, "colorwheel_dark"))
+		cairo_set_source_rgb (cr, 1., 1., 1.);
+	else
+		gdk_cairo_set_source_color_alpha (cr, &style->fg[state_type], 0.7);
+
+	cairo_set_line_width (cr, line_width);
+
+	if (dash_list[0])
+	{
+		gint n_dashes = strlen (dash_list);
+		gdouble *dashes = g_new (gdouble, n_dashes);
+		gdouble total_length = 0;
+		gdouble dash_offset;
+		gint i;
+
+		for (i = 0; i < n_dashes; i++)
+		{
+			dashes[i] = dash_list[i];
+			total_length += dash_list[i];
+		}
+
+		dash_offset = -line_width / 2.;
+		while (dash_offset < 0)
+			dash_offset += total_length;
+
+		cairo_set_dash (cr, dashes, n_dashes, dash_offset);
+		g_free (dashes);
+	}
+
+	if (area)
+	{
+		gdk_cairo_rectangle (cr, area);
+		cairo_clip (cr);
+	}
+
+	cairo_rectangle (cr, x + line_width / 2., y + line_width / 2., width - line_width, height - line_width);
+	cairo_stroke (cr);
+	cairo_destroy (cr);
+
+	if (free_dash_list)
+		g_free (dash_list);
+}
+
+static void
+murrine_style_copy (GtkStyle * style, GtkStyle * src)
+{
+	MurrineStyle * mrn_style = MURRINE_STYLE (style);
+	MurrineStyle * mrn_src = MURRINE_STYLE (src);
+
+	mrn_style->animation           = mrn_src->animation;
+	mrn_style->colorize_scrollbar  = mrn_src->colorize_scrollbar;
+	mrn_style->colors              = mrn_src->colors;
+	mrn_style->glazestyle          = mrn_src->glazestyle;
+	mrn_style->gradient_stop_1     = mrn_src->gradient_stop_1;
+	mrn_style->gradient_stop_2     = mrn_src->gradient_stop_2;
+	mrn_style->gradient_stop_3     = mrn_src->gradient_stop_3;
+	mrn_style->gradient_stop_4     = mrn_src->gradient_stop_4;
+	mrn_style->gradients           = mrn_src->gradients;
+	mrn_style->has_gradient_stop   = mrn_src->has_gradient_stop;
+	mrn_style->has_scrollbar_color = mrn_src->has_scrollbar_color;
+	mrn_style->highlight_ratio     = mrn_src->highlight_ratio;
+	mrn_style->innerborder_ratio   = mrn_src->innerborder_ratio;
+	mrn_style->listviewheaderstyle = mrn_src->listviewheaderstyle;
+	mrn_style->listviewstyle       = mrn_src->listviewstyle;
+	mrn_style->menubaritemstyle    = mrn_src->menubaritemstyle;
+	mrn_style->menubarstyle        = mrn_src->menubarstyle;
+	mrn_style->menuitemstyle       = mrn_src->menuitemstyle;
+	mrn_style->menustyle           = mrn_src->menustyle;
+	mrn_style->rgba                = mrn_src->rgba;
+	mrn_style->roundness           = mrn_src->roundness;
+	mrn_style->scrollbar_color     = mrn_src->scrollbar_color;
+	mrn_style->scrollbarstyle      = mrn_src->scrollbarstyle;
+	mrn_style->sliderstyle 	       = mrn_src->sliderstyle;
+	mrn_style->stepperstyle        = mrn_src->stepperstyle;
+	mrn_style->style               = mrn_src->style;
+	mrn_style->toolbarstyle        = mrn_src->toolbarstyle;
+
+	murrine_parent_class->copy (style, src);
+}
+
+static void
+murrine_style_unrealize (GtkStyle * style)
+{
+	murrine_parent_class->unrealize (style);
+}
+
+static GdkPixbuf *
+set_transparency (const GdkPixbuf *pixbuf, gdouble alpha_percent)
+{
+	GdkPixbuf *target;
+	guchar *data, *current;
+	guint x, y, rowstride, height, width;
+
+	g_return_val_if_fail (pixbuf != NULL, NULL);
+	g_return_val_if_fail (GDK_IS_PIXBUF (pixbuf), NULL);
+
+	/* Returns a copy of pixbuf with it's non-completely-transparent pixels to
+	   have an alpha level "alpha_percent" of their original value. */
+
+	target = gdk_pixbuf_add_alpha (pixbuf, FALSE, 0, 0, 0);
+
+	if (alpha_percent == 1.0)
+		return target;
+	width = gdk_pixbuf_get_width (target);
+	height = gdk_pixbuf_get_height (target);
+	rowstride = gdk_pixbuf_get_rowstride (target);
+	data = gdk_pixbuf_get_pixels (target);
+
+	for (y = 0; y < height; y++)
+	{
+		for (x = 0; x < width; x++)
+		{
+			/* The "4" is the number of chars per pixel, in this case, RGBA,
+			   the 3 means "skip to the alpha" */
+			current = data + (y * rowstride) + (x * 4) + 3;
+			*(current) = (guchar) (*(current) * alpha_percent);
+		}
+	}
+
+	return target;
+}
+
+static GdkPixbuf*
+scale_or_ref (GdkPixbuf *src,
+              int       width,
+              int       height)
+{
+	if (width == gdk_pixbuf_get_width (src) &&
+	    height == gdk_pixbuf_get_height (src))
+	{
+		return g_object_ref (src);
+	}
+	else
+	{
+		return gdk_pixbuf_scale_simple (src, width, height, GDK_INTERP_BILINEAR);
+	}
+}
+
+static GdkPixbuf *
+murrine_style_draw_render_icon (GtkStyle            *style,
+                                const GtkIconSource *source,
+                                GtkTextDirection    direction,
+                                GtkStateType        state,
+                                GtkIconSize         size,
+                                GtkWidget           *widget,
+                                const char          *detail)
+{
+	int width = 1;
+	int height = 1;
+	GdkPixbuf *scaled;
+	GdkPixbuf *stated;
+	GdkPixbuf *base_pixbuf;
+	GdkScreen *screen;
+	GtkSettings *settings;
+
+	/* Oddly, style can be NULL in this function, because
+	 * GtkIconSet can be used without a style and if so
+	 * it uses this function.
+	 */
+
+	base_pixbuf = gtk_icon_source_get_pixbuf (source);
+
+	g_return_val_if_fail (base_pixbuf != NULL, NULL);
+
+	if (widget && gtk_widget_has_screen (widget))
+	{
+		screen = gtk_widget_get_screen (widget);
+		settings = gtk_settings_get_for_screen (screen);
+	}
+	else if (style->colormap)
+	{
+		screen = gdk_colormap_get_screen (style->colormap);
+		settings = gtk_settings_get_for_screen (screen);
+	}
+	else
+	{
+		settings = gtk_settings_get_default ();
+		GTK_NOTE (MULTIHEAD,
+		g_warning ("Using the default screen for gtk_default_murrine_style_draw_render_icon()"));
+	}
+
+	if (size != (GtkIconSize) -1 && !gtk_icon_size_lookup_for_settings (settings, size, &width, &height))
+	{
+		g_warning (G_STRLOC ": invalid icon size '%d'", size);
+		return NULL;
+	}
+
+	/* If the size was wildcarded, and we're allowed to scale, then scale; otherwise,
+	 * leave it alone.
+	 */
+	if (size != (GtkIconSize)-1 && gtk_icon_source_get_size_wildcarded (source))
+		scaled = scale_or_ref (base_pixbuf, width, height);
+	else
+		scaled = g_object_ref (base_pixbuf);
+
+	/* If the state was wildcarded, then generate a state. */
+	if (gtk_icon_source_get_state_wildcarded (source))
+	{
+		if (state == GTK_STATE_INSENSITIVE)
+		{
+			stated = set_transparency (scaled, 0.3);
+#if 0
+			stated =
+				gdk_pixbuf_composite_color_simple (scaled,
+				                                   gdk_pixbuf_get_width (scaled),
+				                                   gdk_pixbuf_get_height (scaled),
+				                                   GDK_INTERP_BILINEAR, 128,
+				                                   gdk_pixbuf_get_width (scaled),
+				                                   style->bg[state].pixel,
+				                                   style->bg[state].pixel);
+#endif
+			gdk_pixbuf_saturate_and_pixelate (stated, stated, 0.1, FALSE);
+
+			g_object_unref (scaled);
+		}
+		else if (state == GTK_STATE_PRELIGHT)
+		{
+			stated = gdk_pixbuf_copy (scaled);
+
+			gdk_pixbuf_saturate_and_pixelate (scaled, stated, 1.2, FALSE);
+
+			g_object_unref (scaled);
+		}
+		else
+		{
+			stated = scaled;
+		}
+	}
+	else
+		stated = scaled;
+
+	return stated;
+}
+
+static void
+murrine_style_init (MurrineStyle * style)
+{
+}
+
+static void
+murrine_style_class_init (MurrineStyleClass * klass)
+{
+	GtkStyleClass *style_class = GTK_STYLE_CLASS (klass);
+
+	murrine_style_class = MURRINE_STYLE_CLASS (klass);
+	murrine_parent_class = g_type_class_peek_parent (klass);
+
+	style_class->copy             = murrine_style_copy;
+	style_class->realize          = murrine_style_realize;
+	style_class->unrealize        = murrine_style_unrealize;
+	style_class->init_from_rc     = murrine_style_init_from_rc;
+	style_class->draw_handle      = murrine_style_draw_handle;
+	style_class->draw_slider      = murrine_style_draw_slider;
+	style_class->draw_shadow_gap  = murrine_style_draw_shadow_gap;
+	style_class->draw_focus       = murrine_style_draw_focus;
+	style_class->draw_box         = murrine_style_draw_box;
+	style_class->draw_shadow      = murrine_style_draw_shadow;
+	style_class->draw_box_gap     = murrine_style_draw_box_gap;
+	style_class->draw_extension   = murrine_style_draw_extension;
+	style_class->draw_option      = murrine_style_draw_option;
+	style_class->draw_check       = murrine_style_draw_check;
+	style_class->draw_flat_box    = murrine_style_draw_flat_box;
+	style_class->draw_tab         = murrine_style_draw_tab;
+	style_class->draw_vline       = murrine_style_draw_vline;
+	style_class->draw_hline       = murrine_style_draw_hline;
+	style_class->draw_resize_grip = murrine_style_draw_resize_grip;
+	style_class->draw_arrow       = murrine_style_draw_arrow;
+	style_class->draw_layout      = murrine_style_draw_layout;
+	style_class->render_icon      = murrine_style_draw_render_icon;
+
+	murrine_register_style_murrine (&murrine_style_class->style_functions[MRN_DRAW_STYLE_MURRINE]);
+	murrine_style_class->style_functions[MRN_DRAW_STYLE_RGBA] = murrine_style_class->style_functions[MRN_DRAW_STYLE_MURRINE];
+	murrine_register_style_rgba (&murrine_style_class->style_functions[MRN_DRAW_STYLE_RGBA]);
+}
+
+GType murrine_type_style = 0;
+
+void
+murrine_style_register_type (GTypeModule * module)
+{
+	static const GTypeInfo object_info =
+	{
+		sizeof (MurrineStyleClass),
+		(GBaseInitFunc) NULL,
+		(GBaseFinalizeFunc) NULL,
+		(GClassInitFunc) murrine_style_class_init,
+		NULL, /* class_finalize */
+		NULL, /* class_data */
+		sizeof (MurrineStyle),
+		0, /* n_preallocs */
+		(GInstanceInitFunc) murrine_style_init,
+		NULL
+	};
+
+	murrine_type_style = g_type_module_register_type (module, GTK_TYPE_STYLE, "MurrineStyle", &object_info, 0);
+}

Added: trunk/src/murrine_style.h
==============================================================================
--- (empty file)
+++ trunk/src/murrine_style.h	Mon Feb 11 23:01:49 2008
@@ -0,0 +1,89 @@
+/* Murrine theme engine
+ * Copyright (C) 2007 Andrea Cimitan
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include <gtk/gtkstyle.h>
+
+#ifndef MURRINE_STYLE_H
+#define MURRINE_STYLE_H
+
+#include "animation.h"
+#include "murrine_types.h"
+
+typedef struct _MurrineStyle MurrineStyle;
+typedef struct _MurrineStyleClass MurrineStyleClass;
+
+G_GNUC_INTERNAL extern GType murrine_type_style;
+
+#define MURRINE_TYPE_STYLE              murrine_type_style
+#define MURRINE_STYLE(object)           (G_TYPE_CHECK_INSTANCE_CAST ((object), MURRINE_TYPE_STYLE, MurrineStyle))
+#define MURRINE_STYLE_CLASS(klass)      (G_TYPE_CHECK_CLASS_CAST ((klass), MURRINE_TYPE_STYLE, MurrineStyleClass))
+#define MURRINE_IS_STYLE(object)        (G_TYPE_CHECK_INSTANCE_TYPE ((object), MURRINE_TYPE_STYLE))
+#define MURRINE_IS_STYLE_CLASS(klass)   (G_TYPE_CHECK_CLASS_TYPE ((klass), MURRINE_TYPE_STYLE))
+#define MURRINE_STYLE_GET_CLASS(obj)    (G_TYPE_INSTANCE_GET_CLASS ((obj), MURRINE_TYPE_STYLE, MurrineStyleClass))
+
+struct _MurrineStyle
+{
+	GtkStyle parent_instance;
+
+	MurrineColors colors;
+	
+	MurrineStyles style;
+	
+	double   contrast;
+	double   gradient_stop_1;
+	double   gradient_stop_2;
+	double   gradient_stop_3;
+	double   gradient_stop_4;
+	double   highlight_ratio;
+	double   innerborder_ratio;
+
+	guint8   glazestyle;
+	guint8   listviewheaderstyle;
+	guint8   listviewstyle;
+	guint8   menubaritemstyle;
+	guint8   menubarstyle;
+	guint8   menuitemstyle;
+	guint8   menustyle;
+	guint8   roundness;
+	guint8   scrollbarstyle;
+	guint8   sliderstyle;
+	guint8   stepperstyle;
+	guint8   toolbarstyle;
+
+	gboolean animation;
+	gboolean gradients;
+	gboolean colorize_scrollbar;
+	gboolean has_gradient_stop;
+	gboolean has_scrollbar_color;
+	gboolean rgba;
+
+	GdkColor scrollbar_color;
+};
+
+struct _MurrineStyleClass
+{
+	GtkStyleClass parent_class;
+	
+	MurrineStyleFunctions style_functions[MRN_NUM_DRAW_STYLES];
+};
+
+G_GNUC_INTERNAL void murrine_style_register_type (GTypeModule *module);
+
+#endif /* MURRINE_STYLE_H */

Added: trunk/src/murrine_theme_main.c
==============================================================================
--- (empty file)
+++ trunk/src/murrine_theme_main.c	Mon Feb 11 23:01:49 2008
@@ -0,0 +1,56 @@
+/* Murrine theme engine
+ * Copyright (C) 2007 Andrea Cimitan
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include <gmodule.h>
+#include <gtk/gtk.h>
+
+#include "murrine_style.h"
+#include "murrine_rc_style.h"
+
+G_MODULE_EXPORT void
+theme_init (GTypeModule *module)
+{
+	murrine_rc_style_register_type (module);
+	murrine_style_register_type (module);
+}
+
+G_MODULE_EXPORT void
+theme_exit (void)
+{
+}
+
+G_MODULE_EXPORT GtkRcStyle *
+theme_create_rc_style (void)
+{
+	return GTK_RC_STYLE (g_object_new (MURRINE_TYPE_RC_STYLE, NULL));
+}
+
+/* The following function will be called by GTK+ when the module
+ * is loaded and checks to see if we are compatible with the
+ * version of GTK+ that loads us.
+ */
+G_MODULE_EXPORT const gchar* g_module_check_init (GModule *module);
+const gchar*
+g_module_check_init (GModule *module)
+{
+	return gtk_check_version (GTK_MAJOR_VERSION,
+	                          GTK_MINOR_VERSION,
+	                          GTK_MICRO_VERSION - GTK_INTERFACE_AGE);
+}

Added: trunk/src/murrine_types.h
==============================================================================
--- (empty file)
+++ trunk/src/murrine_types.h	Mon Feb 11 23:01:49 2008
@@ -0,0 +1,488 @@
+/* Murrine theme engine
+ * Copyright (C) 2007 Andrea Cimitan
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ */
+
+#ifndef MURRINE_TYPES_H
+#define MURRINE_TYPES_H
+
+typedef unsigned char boolean;
+typedef unsigned char uint8;
+typedef struct _MurrineStyleFunctions MurrineStyleFunctions;
+
+typedef enum
+{
+	MRN_STYLE_MURRINE = 0,
+	MRN_STYLE_NODOKA = 1,
+	MRN_STYLE_MIST = 2,
+	MRN_STYLE_CANDIDO = 3,
+	MRN_STYLE_CLEARLOOKS = 4,
+	MRN_NUM_STYLES = 5
+} MurrineStyles;
+
+typedef enum
+{
+	MRN_DRAW_STYLE_MURRINE = 0,
+	MRN_DRAW_STYLE_RGBA = 1,
+	MRN_NUM_DRAW_STYLES = 2
+} MurrineDrawStyles;
+
+typedef enum
+{
+	MRN_STATE_NORMAL,
+	MRN_STATE_ACTIVE,
+	MRN_STATE_SELECTED,
+	MRN_STATE_INSENSITIVE
+} MurrineStateType;
+
+typedef enum
+{
+	MRN_CORNER_NONE        = 0,
+	MRN_CORNER_TOPLEFT     = 1,
+	MRN_CORNER_TOPRIGHT    = 2,
+	MRN_CORNER_BOTTOMLEFT  = 4,
+	MRN_CORNER_BOTTOMRIGHT = 8,
+	MRN_CORNER_ALL         = 15
+} MurrineCorners;
+
+typedef enum
+{
+	MRN_JUNCTION_NONE      = 0,
+	MRN_JUNCTION_BEGIN     = 1,
+	MRN_JUNCTION_END       = 2
+} MurrineJunction;
+
+typedef enum
+{
+	MRN_STEPPER_UNKNOWN    = 0,
+	MRN_STEPPER_A          = 1,
+	MRN_STEPPER_B          = 2,
+	MRN_STEPPER_C          = 4,
+	MRN_STEPPER_D          = 8
+} MurrineStepper;
+
+typedef enum
+{
+	MRN_ORDER_FIRST,
+	MRN_ORDER_MIDDLE,
+	MRN_ORDER_LAST
+} MurrineOrder;
+
+typedef enum
+{
+	MRN_ORIENTATION_LEFT_TO_RIGHT,
+	MRN_ORIENTATION_RIGHT_TO_LEFT,
+	MRN_ORIENTATION_BOTTOM_TO_TOP,
+	MRN_ORIENTATION_TOP_TO_BOTTOM
+} MurrineOrientation;
+
+typedef enum
+{
+	MRN_GAP_LEFT,
+	MRN_GAP_RIGHT,
+	MRN_GAP_TOP,
+	MRN_GAP_BOTTOM
+} MurrineGapSide;
+
+typedef enum
+{
+	MRN_SHADOW_NONE,
+	MRN_SHADOW_IN,
+	MRN_SHADOW_OUT,
+	MRN_SHADOW_ETCHED_IN,
+	MRN_SHADOW_ETCHED_OUT,
+	MRN_SHADOW_FLAT
+} MurrineShadowType;
+
+typedef enum
+{
+	MRN_HANDLE_TOOLBAR,
+	MRN_HANDLE_SPLITTER
+} MurrineHandleType;
+
+typedef enum
+{
+	MRN_ARROW_NORMAL,
+	MRN_ARROW_COMBO
+} MurrineArrowType;
+
+typedef enum
+{
+	MRN_DIRECTION_UP,
+	MRN_DIRECTION_DOWN,
+	MRN_DIRECTION_LEFT,
+	MRN_DIRECTION_RIGHT
+} MurrineDirection;
+
+typedef enum
+{
+	MRN_PROGRESSBAR_CONTINUOUS,
+	MRN_PROGRESSBAR_DISCRETE
+} MurrineProgressBarStyle;
+
+typedef enum
+{
+	MRN_WINDOW_EDGE_NORTH_WEST,
+	MRN_WINDOW_EDGE_NORTH,
+	MRN_WINDOW_EDGE_NORTH_EAST,
+	MRN_WINDOW_EDGE_WEST,
+	MRN_WINDOW_EDGE_EAST,
+	MRN_WINDOW_EDGE_SOUTH_WEST,
+	MRN_WINDOW_EDGE_SOUTH,
+	MRN_WINDOW_EDGE_SOUTH_EAST
+} MurrineWindowEdge;
+
+typedef struct
+{
+	double r;
+	double g;
+	double b;
+} MurrineRGB;
+
+typedef struct
+{
+	double x;
+	double y;
+	double width;
+	double height;
+} MurrineRectangle;
+
+typedef struct
+{
+	MurrineRGB bg[5];
+	MurrineRGB base[5];
+	MurrineRGB text[5];
+	MurrineRGB fg[5];
+
+	MurrineRGB shade[9];
+	MurrineRGB spot[3];
+} MurrineColors;
+
+typedef struct
+{
+	double  gradient_stop_1;
+	double  gradient_stop_2;
+	double  gradient_stop_3;
+	double  gradient_stop_4;
+	double  rgba_opacity;
+
+	boolean gradients;
+	boolean has_gradient_stop;
+	boolean use_rgba;
+} MurrineGradients;
+
+typedef struct
+{
+	boolean active;
+	boolean prelight;
+	boolean disabled;
+	boolean ltr;
+	boolean focus;
+	boolean is_default;
+	MurrineStateType state_type;
+	uint8 corners;
+	uint8 xthickness;
+	uint8 ythickness;
+	MurrineRGB parentbg;
+
+	/* Style */
+	int glazestyle;
+	int roundness;
+	double highlight_ratio;
+	double innerborder_ratio;
+	MurrineGradients mrn_gradient;
+
+	MurrineDrawStyles drawstyle;
+	MurrineStyleFunctions *style_functions;
+} WidgetParameters;
+
+typedef struct
+{
+	boolean inverted;
+	int     fill_size;
+	boolean horizontal;
+} SliderParameters;
+
+typedef struct
+{
+	MurrineOrientation orientation;
+	MurrineProgressBarStyle style;
+} ProgressBarParameters;
+
+typedef struct
+{
+	int linepos;
+} OptionMenuParameters;
+
+typedef struct
+{
+	boolean inconsistent;
+	boolean draw_bullet;
+} OptionParameters;
+
+typedef struct
+{
+	MurrineShadowType shadow;
+	MurrineGapSide gap_side;
+	int gap_x;
+	int gap_width;
+	MurrineRGB *border;
+} FrameParameters;
+
+typedef struct
+{
+	MurrineGapSide gap_side;
+} TabParameters;
+
+typedef struct
+{
+	MurrineCorners    corners;
+	MurrineShadowType shadow;
+} ShadowParameters;
+
+typedef struct
+{
+	boolean horizontal;
+	boolean use_rgba;
+} SeparatorParameters;
+
+typedef struct
+{
+	MurrineOrder   order;
+	boolean        resizable;
+	int            style;
+} ListViewHeaderParameters;
+
+typedef struct
+{
+	MurrineRGB      color;
+	MurrineJunction junction; /* On which sides the slider junctions */
+	MurrineStepper  steppers; /* The visible steppers */
+	boolean         horizontal;
+	boolean         has_color;
+	int             style;
+	int             stepperstyle;
+} ScrollBarParameters;
+
+typedef struct
+{
+	MurrineHandleType type;
+	boolean           horizontal;
+} HandleParameters;
+
+typedef struct
+{
+	MurrineStepper stepper; /* Which stepper to draw */
+} ScrollBarStepperParameters;
+
+typedef struct
+{
+	MurrineArrowType type;
+	MurrineDirection direction;
+} ArrowParameters;
+
+typedef struct
+{
+	MurrineWindowEdge edge;
+} ResizeGripParameters;
+
+typedef struct
+{
+	boolean topmost;
+	int style;
+} ToolbarParameters;
+
+struct _MurrineStyleFunctions
+{
+	void (*draw_button) (cairo_t *cr,
+	                     const MurrineColors    *colors,
+	                     const WidgetParameters *widget,
+	                     int x, int y, int width, int height,
+	                     boolean vertical);
+
+	void (*draw_scale_trough) (cairo_t *cr,
+	                           const MurrineColors    *colors,
+	                           const WidgetParameters *widget,
+	                           const SliderParameters *slider,
+	                           int x, int y, int width, int height);
+
+	void (*draw_slider_handle) (cairo_t *cr,
+	                            const MurrineColors    *colors,
+	                            const WidgetParameters *widget,
+	                            int x, int y, int width, int height,
+	                            boolean horizontal);
+
+	void (*draw_progressbar_trough) (cairo_t *cr,
+	                                 const MurrineColors    *colors,
+	                                 const WidgetParameters *widget,
+	                                 int x, int y, int width, int height);
+
+	void (*draw_progressbar_fill) (cairo_t *cr,
+	                               const MurrineColors         *colors,
+	                               const WidgetParameters      *widget,
+	                               const ProgressBarParameters *progressbar,
+	                               int x, int y, int width, int height,
+	                               gint offset);
+
+	void (*draw_entry) (cairo_t *cr,
+	                    const MurrineColors    *colors,
+	                    const WidgetParameters *widget,
+	                    int x, int y, int width, int height);
+
+	void (*draw_spinbutton) (cairo_t *cr,
+	                         const MurrineColors    *colors,
+	                         const WidgetParameters *widget,
+	                         int x, int y, int width, int height);
+
+	void (*draw_spinbutton_down) (cairo_t *cr,
+	                              const MurrineColors    *colors,
+	                              const WidgetParameters *widget,
+	                              int x, int y, int width, int height);
+
+	void (*draw_optionmenu) (cairo_t *cr,
+	                         const MurrineColors        *colors,
+	                         const WidgetParameters     *widget,
+	                         const OptionMenuParameters *optionmenu,
+	                         int x, int y, int width, int height);
+
+	void (*draw_menubar) (cairo_t *cr,
+	                      const MurrineColors    *colors,
+	                      const WidgetParameters *widget,
+	                      int x, int y, int width, int height,
+	                      int menubarstyle);
+
+	void (*draw_tab) (cairo_t *cr,
+	                  const MurrineColors    *colors,
+	                  const WidgetParameters *widget,
+	                  const TabParameters    *tab,
+	                  int x, int y, int width, int height);
+
+	void (*draw_frame) (cairo_t *cr,
+	                    const MurrineColors    *colors,
+	                    const WidgetParameters *widget,
+	                    const FrameParameters  *frame,
+	                    int x, int y, int width, int height);
+
+	void (*draw_separator) (cairo_t *cr,
+	                        const MurrineColors       *colors,
+	                        const WidgetParameters    *widget,
+	                        const SeparatorParameters *separator,
+	                        int x, int y, int width, int height);
+
+	void (*draw_combo_separator) (cairo_t *cr,
+	                              const MurrineColors    *colors,
+	                              const WidgetParameters *widget,
+	                              int x, int y, int width, int height);
+
+	void (*draw_list_view_header) (cairo_t *cr,
+	                               const MurrineColors            *colors,
+	                               const WidgetParameters         *widget,
+	                               const ListViewHeaderParameters *header,
+	                               int x, int y, int width, int height);
+
+	void (*draw_toolbar) (cairo_t *cr,
+	                      const MurrineColors    *colors,
+	                      const WidgetParameters *widget,
+	                      const ToolbarParameters *toolbar,
+	                      int x, int y, int width, int height);
+
+	void (*draw_menuitem) (cairo_t *cr,
+	                       const MurrineColors    *colors,
+	                       const WidgetParameters *widget,
+	                       int x, int y, int width, int height,
+	                       int menuitemstyle);
+
+	void (*draw_scrollbar_stepper) (cairo_t *cr,
+	                                const MurrineColors              *colors,
+	                                const WidgetParameters           *widget,
+	                                const ScrollBarParameters        *scrollbar,
+	                                //const ScrollBarStepperParameters *stepper,
+	                                int x, int y, int width, int height);
+
+	void (*draw_scrollbar_slider) (cairo_t *cr,
+	                               const MurrineColors       *colors,
+	                               const WidgetParameters    *widget,
+	                               const ScrollBarParameters *scrollbar,
+	                               int x, int y, int width, int height);
+
+	void (*draw_scrollbar_trough) (cairo_t *cr,
+	                               const MurrineColors       *colors,
+	                               const WidgetParameters    *widget,
+	                               const ScrollBarParameters *scrollbar,
+	                               int x, int y, int width, int height);
+
+	void (*draw_selected_cell) (cairo_t *cr,
+	                            const MurrineColors    *colors,
+	                            const WidgetParameters *widget,
+	                            int x, int y, int width, int height);
+
+	void (*draw_statusbar) (cairo_t *cr,
+	                        const MurrineColors    *colors,
+	                        const WidgetParameters *widget,
+	                        int x, int y, int width, int height);
+
+	void (*draw_menu_frame) (cairo_t *cr,
+	                         const MurrineColors    *colors,
+	                         const WidgetParameters *widget,
+	                         int x, int y, int width, int height,
+	                         int menustyle);
+
+	void (*draw_tooltip) (cairo_t *cr,
+	                      const MurrineColors    *colors,
+	                      const WidgetParameters *widget,
+	                      int x, int y, int width, int height);
+
+	void (*draw_handle) (cairo_t *cr,
+	                     const MurrineColors    *colors,
+	                     const WidgetParameters *widget,
+	                     const HandleParameters *handle,
+	                     int x, int y, int width, int height);
+
+	void (*draw_arrow) (cairo_t *cr,
+	                    const MurrineColors    *colors,
+	                    const WidgetParameters *widget,
+	                    const ArrowParameters  *arrow,
+	                    int x, int y, int width, int height);
+
+	void (*draw_checkbox) (cairo_t *cr,
+	                       const MurrineColors    *colors,
+	                       const WidgetParameters *widget,
+	                       const OptionParameters *status,
+	                       int x, int y, int width, int height,
+	                       double trans);
+
+	void (*draw_radiobutton) (cairo_t *cr,
+	                          const MurrineColors    *colors,
+	                          const WidgetParameters *widget,
+	                          const OptionParameters *status,
+	                          int x, int y, int width, int height,
+	                          double trans);
+
+	void (*draw_resize_grip) (cairo_t *cr,
+	                          const MurrineColors        *colors,
+	                          const WidgetParameters     *widget,
+	                          const ResizeGripParameters *grip,
+	                          int x, int y, int width, int height);
+};
+
+#define MURRINE_RECTANGLE_SET(rect, _x, _y, _w, _h) rect.x      = _x; \
+                                                    rect.y      = _y; \
+                                                    rect.width  = _w; \
+                                                    rect.height = _h;
+
+#endif /* MURRINE_TYPES_H */

Added: trunk/src/support.c
==============================================================================
--- (empty file)
+++ trunk/src/support.c	Mon Feb 11 23:01:49 2008
@@ -0,0 +1,411 @@
+/* Murrine theme engine
+ * Copyright (C) 2007 Andrea Cimitan
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include "support.h"
+#include "cairo-support.h"
+
+GtkTextDirection
+murrine_get_direction (GtkWidget *widget)
+{
+	GtkTextDirection dir;
+	
+	if (widget)
+		dir = gtk_widget_get_direction (widget);
+	else
+		dir = GTK_TEXT_DIR_LTR;
+	
+	return dir;
+}
+
+void murrine_gtk_treeview_get_header_index (GtkTreeView *tv, GtkWidget *header,
+                                            gint *column_index, gint *columns,
+                                            gboolean *resizable)
+{
+	GList *list, *list_start;
+	*column_index = *columns = 0;
+	list_start = list = gtk_tree_view_get_columns (tv);
+
+	do
+	{
+		GtkTreeViewColumn *column = GTK_TREE_VIEW_COLUMN(list->data);
+		if ( column->button == header )
+		{
+			*column_index = *columns;
+			*resizable = column->resizable;
+		}
+		if ( column->visible )
+			(*columns)++;
+	} while ((list = g_list_next(list)));
+
+	g_list_free (list_start);
+}
+
+void murrine_gtk_clist_get_header_index (GtkCList *clist, GtkWidget *button,
+                                         gint *column_index, gint *columns)
+{
+	int i;
+	*columns = clist->columns;
+	
+	for (i=0; i<*columns; i++)
+	{
+		if (clist->column[i].button == button)
+		{
+			*column_index = i;
+			break;
+		}
+	}
+}
+
+static GtkRequisition default_option_indicator_size = { 7, 13 };
+static GtkBorder default_option_indicator_spacing = { 7, 5, 2, 2 };
+
+void
+murrine_option_menu_get_props (GtkWidget      *widget,
+                               GtkRequisition *indicator_size,
+                               GtkBorder      *indicator_spacing)
+{
+	GtkRequisition *tmp_size = NULL;
+	GtkBorder *tmp_spacing = NULL;
+	
+	if (widget)
+		gtk_widget_style_get (widget, "indicator_size", &tmp_size,
+		                      "indicator_spacing", &tmp_spacing, NULL);
+	
+	if (tmp_size)
+	{
+		*indicator_size = *tmp_size;
+		gtk_requisition_free (tmp_size);
+	}
+	else
+		*indicator_size = default_option_indicator_size;
+	
+	if (tmp_spacing)
+	{
+		*indicator_spacing = *tmp_spacing;
+		gtk_border_free (tmp_spacing);
+	}
+	else
+		*indicator_spacing = default_option_indicator_spacing;
+}
+
+GtkWidget *murrine_special_get_ancestor(GtkWidget * widget, GType widget_type)
+{
+	g_return_val_if_fail(GTK_IS_WIDGET(widget), NULL);
+
+	while (widget && widget->parent
+	       && !g_type_is_a(GTK_WIDGET_TYPE(widget->parent),
+	       widget_type))
+		widget = widget->parent;
+
+	if (!
+	    (widget && widget->parent
+	     && g_type_is_a(GTK_WIDGET_TYPE(widget->parent), widget_type)))
+		return NULL;
+
+	return widget;
+}
+
+GtkWidget *murrine_get_parent_window (GtkWidget *widget)
+{
+	GtkWidget *parent = widget->parent;
+
+	while (parent && GTK_WIDGET_NO_WINDOW (parent))
+		parent = parent->parent;
+
+	return parent;
+}
+
+GdkColor *murrine_get_parent_bgcolor (GtkWidget *widget)
+{
+	GtkWidget *parent = murrine_get_parent_window (widget);
+
+	if (parent && parent->style)
+		return &parent->style->bg[GTK_STATE_NORMAL];
+
+	return NULL;
+}
+
+gboolean
+murrine_object_is_a (const GObject * object, const gchar * type_name)
+{
+	gboolean result = FALSE;
+
+	if ((object))
+	{
+		GType tmp = g_type_from_name (type_name);
+
+		if (tmp)
+			result = g_type_check_instance_is_a ((GTypeInstance *) object, tmp);
+	}
+
+	return result;
+}
+
+gboolean
+murrine_widget_is_ltr (GtkWidget *widget)
+{
+	GtkTextDirection dir = GTK_TEXT_DIR_NONE;
+	
+	if (MRN_IS_WIDGET (widget))
+		dir = gtk_widget_get_direction (widget);
+
+	if (dir == GTK_TEXT_DIR_NONE)
+		dir = gtk_widget_get_default_direction ();
+
+	if (dir == GTK_TEXT_DIR_RTL)
+		return FALSE;
+	else
+		return TRUE;
+}
+
+GtkWidget *
+murrine_find_combo_box_widget (GtkWidget * widget)
+{
+	GtkWidget *result = NULL;
+	
+	if (widget && !GTK_IS_COMBO_BOX_ENTRY (widget))
+	{
+		if (GTK_IS_COMBO_BOX (widget))
+			result = widget;
+		else
+			result = murrine_find_combo_box_widget(widget->parent);
+	}
+	
+	return result;
+}
+
+gboolean
+murrine_is_combo_box (GtkWidget * widget)
+{
+	return (murrine_find_combo_box_widget(widget) != NULL);
+}
+
+MurrineStepper
+murrine_scrollbar_get_stepper (GtkWidget    *widget,
+                               GdkRectangle *stepper)
+{
+	MurrineStepper value = MRN_STEPPER_UNKNOWN;
+	GdkRectangle tmp;
+	GdkRectangle check_rectangle;
+	GtkOrientation orientation;
+
+	g_return_val_if_fail (GTK_IS_RANGE (widget), MRN_STEPPER_UNKNOWN);
+
+	check_rectangle.x      = widget->allocation.x;
+	check_rectangle.y      = widget->allocation.y;
+	check_rectangle.width  = stepper->width;
+	check_rectangle.height = stepper->height;
+	
+	orientation = GTK_RANGE (widget)->orientation;
+	
+	if (widget->allocation.x == -1 && widget->allocation.y == -1)
+		return MRN_STEPPER_UNKNOWN;
+		
+	if (gdk_rectangle_intersect (stepper, &check_rectangle, &tmp))
+		value = MRN_STEPPER_A;
+
+	if (value == MRN_STEPPER_UNKNOWN) /* Haven't found a match */
+	{
+		if (orientation == GTK_ORIENTATION_HORIZONTAL)
+			check_rectangle.x = widget->allocation.x + stepper->width;
+		else
+			check_rectangle.y = widget->allocation.y + stepper->height;
+		
+		if (gdk_rectangle_intersect (stepper, &check_rectangle, &tmp))
+			value = MRN_STEPPER_B;
+	}
+
+	if (value == MRN_STEPPER_UNKNOWN) /* Still haven't found a match */
+	{
+		if (orientation == GTK_ORIENTATION_HORIZONTAL)
+			check_rectangle.x = widget->allocation.x + widget->allocation.width - (stepper->width * 2);
+		else
+			check_rectangle.y = widget->allocation.y + widget->allocation.height - (stepper->height * 2);
+		
+		if (gdk_rectangle_intersect (stepper, &check_rectangle, &tmp))
+			value = MRN_STEPPER_C;
+	}
+
+	if (value == MRN_STEPPER_UNKNOWN) /* STILL haven't found a match */
+	{
+		if (orientation == GTK_ORIENTATION_HORIZONTAL)
+			check_rectangle.x = widget->allocation.x + widget->allocation.width - stepper->width;
+		else
+			check_rectangle.y = widget->allocation.y + widget->allocation.height - stepper->height;
+		
+		if (gdk_rectangle_intersect (stepper, &check_rectangle, &tmp))
+			value = MRN_STEPPER_D;
+	}
+	
+	return value;
+}
+
+MurrineStepper
+murrine_scrollbar_visible_steppers (GtkWidget *widget)
+{
+	MurrineStepper steppers = 0;
+	
+	g_return_val_if_fail (GTK_IS_RANGE (widget), MRN_STEPPER_UNKNOWN);
+	
+	if (GTK_RANGE (widget)->has_stepper_a)
+		steppers |= MRN_STEPPER_A;
+	
+	if (GTK_RANGE (widget)->has_stepper_b)
+		steppers |= MRN_STEPPER_B;
+
+	if (GTK_RANGE (widget)->has_stepper_c)
+		steppers |= MRN_STEPPER_C;
+
+	if (GTK_RANGE (widget)->has_stepper_d)
+		steppers |= MRN_STEPPER_D;
+}
+
+MurrineJunction
+murrine_scrollbar_get_junction (GtkWidget    *widget)
+{	
+	GtkAdjustment *adj;
+	MurrineJunction junction = MRN_JUNCTION_NONE;
+	
+	g_return_val_if_fail (GTK_IS_RANGE (widget), MRN_JUNCTION_NONE);
+
+	adj = GTK_RANGE (widget)->adjustment;
+	
+	if (adj->value <= adj->lower &&
+	    (GTK_RANGE (widget)->has_stepper_a || GTK_RANGE (widget)->has_stepper_b))
+	{
+		junction |= MRN_JUNCTION_BEGIN;
+	}
+	
+	if (adj->value >= adj->upper - adj->page_size &&
+	    (GTK_RANGE (widget)->has_stepper_c || GTK_RANGE (widget)->has_stepper_d))
+	{
+		junction |= MRN_JUNCTION_END;
+	}
+	
+	return junction;
+}
+
+gboolean murrine_is_panel_widget (GtkWidget *widget)
+{
+	return widget && (strcmp(G_OBJECT_TYPE_NAME (widget), "PanelApplet") == 0 ||
+	                  strcmp(G_OBJECT_TYPE_NAME (widget), "PanelWidget") == 0);
+}
+
+void
+murrine_set_toolbar_parameters (ToolbarParameters *toolbar,
+                                GtkWidget *widget,
+                                GdkWindow *window,
+                                gint x, gint y)
+{
+	toolbar->topmost = FALSE;
+
+	if (x == 0 && y == 0)
+	{
+		if (widget && widget->allocation.x == 0 && widget->allocation.y == 0)
+		{
+			if (widget->window == window && MRN_IS_TOOLBAR (widget))
+			{
+				toolbar->topmost = TRUE;
+			}
+		}
+	}
+}
+
+void
+murrine_get_notebook_tab_position (GtkWidget *widget,
+                                   gboolean  *start,
+                                   gboolean  *end)
+{
+	/* default value */
+	*start = TRUE;
+	*end = FALSE;
+
+	if (MRN_IS_NOTEBOOK (widget))
+	{
+		gboolean found_tabs = FALSE;
+		gint i, n_pages;
+		GtkNotebook *notebook = GTK_NOTEBOOK (widget);
+
+		/* got a notebook, so walk over all the tabs and decide based
+		 * on that ...
+		 * It works like this:
+		 *   - If there is any visible tab that is expanded, set both.
+		 *   - Set start/end if there is any visible tab that is at
+		 *     the start/end.
+		 *   - If one has the child_visibility set to false, arrows
+		 *     are present; so none
+		 * The heuristic falls over if there is a notebook that just
+		 * happens to fill up all the available space. ie. All tabs
+		 * are left aligned, but it does not require scrolling.
+		 * (a more complex heuristic could calculate the tabs width
+		 * and add them all up) */
+
+		n_pages = gtk_notebook_get_n_pages (notebook);
+		for (i = 0; i < n_pages; i++)
+		{
+			GtkWidget *tab_child;
+			GtkWidget *tab_label;
+			gboolean expand;
+			GtkPackType pack_type;
+						
+			tab_child = gtk_notebook_get_nth_page (notebook, i);
+
+			/* Skip invisible tabs */
+			tab_label = gtk_notebook_get_tab_label (notebook, tab_child);
+			if (!tab_label || !GTK_WIDGET_VISIBLE (tab_label))
+				continue;
+			/* This is the same what the notebook does internally. */
+			if (tab_label && !gtk_widget_get_child_visible (tab_label))
+			{
+				/* One child is hidden because scroll arrows are present.
+				 * So both corners are rounded. */
+				*start = FALSE;
+				*end = FALSE;
+				return;
+			}
+
+			gtk_notebook_query_tab_label_packing (notebook, tab_child,
+			                                      &expand,
+			                                      NULL, /* don't need fill */
+			                                      &pack_type);
+
+			if (!found_tabs)
+			{
+				found_tabs = TRUE;
+				*start = FALSE;
+				*end = FALSE;
+			}
+
+			if (expand)
+			{
+				*start = TRUE;
+				*end = TRUE;
+			}
+			else if (pack_type == GTK_PACK_START)
+			{
+				*start = TRUE;
+			}
+			else
+			{
+				*end = TRUE;
+			}
+		}
+	}
+}

Added: trunk/src/support.h
==============================================================================
--- (empty file)
+++ trunk/src/support.h	Mon Feb 11 23:01:49 2008
@@ -0,0 +1,154 @@
+/* Murrine theme engine
+ * Copyright (C) 2007 Andrea Cimitan
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ */
+
+#ifndef SUPPORT_H
+#define SUPPORT_H
+
+#include <gtk/gtk.h>
+#include <math.h>
+#include <string.h>
+
+#include "murrine_types.h"
+#include "cairo-support.h"
+
+/* GTK 2.2 compatibility */
+#ifndef GTK_IS_COMBO_BOX_ENTRY
+	#define GTK_IS_COMBO_BOX_ENTRY(x) 0
+#endif
+#ifndef GTK_IS_COMBO_BOX
+	#define GTK_IS_COMBO_BOX(x) 0
+#endif
+
+#define RADIO_SIZE 13
+#define CHECK_SIZE 13
+
+/* Opacity settings */
+#define GRADIENT_OPACITY 0.90
+#define WINDOW_OPACITY 0.84
+#define ENTRY_OPACITY 0.88
+#define NOTEBOOK_OPACITY 0.74
+#define MENUBAR_OPACITY 0.90
+#define MENUBAR_GLOSSY_OPACITY 0.86
+#define MENUBAR_STRIPED_OPACITY 0.94
+#define TOOLBAR_OPACITY 0.87
+#define TOOLBAR_GLOSSY_OPACITY 0.86
+#define MENU_OPACITY 0.90
+
+/* From gtk-engines 20071109 */
+#define MRN_IS_WIDGET(object) ((object)  && murrine_object_is_a ((GObject*)(object), "GtkWidget"))
+#define MRN_IS_CONTAINER(object) ((object)  && murrine_object_is_a ((GObject*)(object), "GtkContainer"))
+#define MRN_IS_BIN(object) ((object)  && murrine_object_is_a ((GObject*)(object), "GtkBin"))
+
+#define MRN_IS_ARROW(object) ((object)  && murrine_object_is_a ((GObject*)(object), "GtkArrow"))
+
+#define MRN_IS_SEPARATOR(object) ((object)  && murrine_object_is_a ((GObject*)(object), "GtkSeparator"))
+#define MRN_IS_VSEPARATOR(object) ((object)  && murrine_object_is_a ((GObject*)(object), "GtkVSeparator"))
+#define MRN_IS_HSEPARATOR(object) ((object)  && murrine_object_is_a ((GObject*)(object), "GtkHSeparator"))
+ 
+#define MRN_IS_HANDLE_BOX(object) ((object) && murrine_object_is_a ((GObject*)(object), "GtkHandleBox"))
+#define MRN_IS_HANDLE_BOX_ITEM(object) ((object) && MRN_IS_HANDLE_BOX(object->parent))
+#define MRN_IS_BONOBO_DOCK_ITEM(object) ((object) && murrine_object_is_a ((GObject*)(object), "BonoboDockItem"))
+#define MRN_IS_BONOBO_DOCK_ITEM_GRIP(object) ((object) && murrine_object_is_a ((GObject*)(object), "BonoboDockItemGrip"))
+#define MRN_IS_BONOBO_TOOLBAR(object) ((object) && murrine_object_is_a ((GObject*)(object), "BonoboUIToolbar"))
+#define MRN_IS_EGG_TOOLBAR(object) ((object) && murrine_object_is_a ((GObject*)(object), "Toolbar"))
+#define MRN_IS_TOOLBAR(object) ((object) && murrine_object_is_a ((GObject*)(object), "GtkToolbar"))
+#define MRN_IS_PANEL_WIDGET(object) ((object) && (murrine_object_is_a ((GObject*)(object), "PanelWidget") || murrine_object_is_a ((GObject*)(object), "PanelApplet")))
+
+#define MRN_IS_COMBO_BOX_ENTRY(object) ((object) && murrine_object_is_a ((GObject*)(object), "GtkComboBoxEntry"))
+#define MRN_IS_COMBO_BOX(object) ((object) && murrine_object_is_a ((GObject*)(object), "GtkComboBox"))
+#define MRN_IS_COMBO(object) ((object) && murrine_object_is_a ((GObject*)(object), "GtkCombo"))
+#define MRN_IS_OPTION_MENU(object) ((object) && murrine_object_is_a ((GObject*)(object), "GtkOptionMenu"))
+ 
+#define MRN_IS_TOGGLE_BUTTON(object) ((object) && murrine_object_is_a ((GObject*)(object), "GtkToggleButton"))
+#define MRN_IS_CHECK_BUTTON(object) ((object) && murrine_object_is_a ((GObject*)(object), "GtkCheckButton"))
+#define MRN_IS_SPIN_BUTTON(object) ((object) && murrine_object_is_a ((GObject*)(object), "GtkSpinButton"))
+ 
+#define MRN_IS_STATUSBAR(object) ((object) && murrine_object_is_a ((GObject*)(object), "GtkStatusbar"))
+#define MRN_IS_PROGRESS_BAR(object) ((object) && murrine_object_is_a ((GObject*)(object), "GtkProgressBar"))
+ 
+#define MRN_IS_MENU_SHELL(object) ((object) && murrine_object_is_a ((GObject*)(object), "GtkMenuShell"))
+#define MRN_IS_MENU(object) ((object) && murrine_object_is_a ((GObject*)(object), "GtkMenu"))
+#define MRN_IS_MENU_BAR(object) ((object) && murrine_object_is_a ((GObject*)(object), "GtkMenuBar"))
+#define MRN_IS_MENU_ITEM(object) ((object) && murrine_object_is_a ((GObject*)(object), "GtkMenuItem"))
+
+#define MRN_IS_CHECK_MENU_ITEM(object) ((object) && murrine_object_is_a ((GObject*)(object), "GtkCheckMenuItem"))
+
+#define MRN_IS_RANGE(object) ((object) && murrine_object_is_a ((GObject*)(object), "GtkRange"))
+ 
+#define MRN_IS_SCROLLBAR(object) ((object) && murrine_object_is_a ((GObject*)(object), "GtkScrollbar"))
+#define MRN_IS_VSCROLLBAR(object) ((object) && murrine_object_is_a ((GObject*)(object), "GtkVScrollbar"))
+#define MRN_IS_HSCROLLBAR(object) ((object) && murrine_object_is_a ((GObject*)(object), "GtkHScrollbar"))
+ 
+#define MRN_IS_SCALE(object) ((object) && murrine_object_is_a ((GObject*)(object), "GtkScale"))
+#define MRN_IS_VSCALE(object) ((object) && murrine_object_is_a ((GObject*)(object), "GtkVScale"))
+#define MRN_IS_HSCALE(object) ((object) && murrine_object_is_a ((GObject*)(object), "GtkHScale"))
+  
+#define MRN_IS_PANED(object) ((object) && murrine_object_is_a ((GObject*)(object), "GtkPaned"))
+#define MRN_IS_VPANED(object) ((object) && murrine_object_is_a ((GObject*)(object), "GtkVPaned"))
+#define MRN_IS_HPANED(object) ((object) && murrine_object_is_a ((GObject*)(object), "GtkHPaned"))
+ 
+#define MRN_IS_BOX(object) ((object) && murrine_object_is_a ((GObject*)(object), "GtkBox"))
+#define MRN_IS_VBOX(object) ((object) && murrine_object_is_a ((GObject*)(object), "GtkVBox"))
+#define MRN_IS_HBOX(object) ((object) && murrine_object_is_a ((GObject*)(object), "GtkHBox"))
+
+#define MRN_IS_CLIST(object) ((object) && murrine_object_is_a ((GObject*)(object), "GtkCList"))
+#define MRN_IS_TREE_VIEW(object) ((object) && murrine_object_is_a ((GObject*)(object), "GtkTreeView"))
+#define MRN_IS_ENTRY(object) ((object) && murrine_object_is_a ((GObject*)(object), "GtkEntry"))
+#define MRN_IS_BUTTON(object) ((object) && murrine_object_is_a ((GObject*)(object), "GtkButton"))
+#define MRN_IS_FIXED(object) ((object) && murrine_object_is_a ((GObject*)(object), "GtkFixed"))
+ 
+#define TOGGLE_BUTTON(object) (MRN_IS_TOGGLE_BUTTON(object)?(GtkToggleButton *)object:NULL)
+ 
+#define MRN_IS_NOTEBOOK(object) ((object) && murrine_object_is_a ((GObject*)(object), "GtkNotebook"))
+#define MRN_IS_CELL_RENDERER_TOGGLE(object) ((object) && murrine_object_is_a ((GObject*)(object), "GtkCellRendererToggle"))
+
+#define MRN_WIDGET_HAS_DEFAULT(object) ((object) && MRN_IS_WIDGET(object) && GTK_WIDGET_HAS_DEFAULT(object))
+
+G_GNUC_INTERNAL GtkTextDirection murrine_get_direction (GtkWidget *widget);
+G_GNUC_INTERNAL GtkWidget *murrine_special_get_ancestor (GtkWidget *widget, GType widget_type);
+G_GNUC_INTERNAL GdkColor* murrine_get_parent_bgcolor (GtkWidget *widget);
+G_GNUC_INTERNAL GtkWidget* murrine_get_parent_window (GtkWidget *widget);
+G_GNUC_INTERNAL gboolean murrine_is_combo_box (GtkWidget *widget);
+G_GNUC_INTERNAL GtkWidget* murrine_find_combo_box_widget(GtkWidget *widget);
+G_GNUC_INTERNAL void murrine_gtk_treeview_get_header_index (GtkTreeView *tv,
+                                                            GtkWidget   *header,
+                                                            gint        *column_index,
+                                                            gint        *columns,
+                                                            gboolean    *resizable);
+G_GNUC_INTERNAL void murrine_gtk_clist_get_header_index (GtkCList  *clist,
+                                                         GtkWidget *button,
+                                                         gint      *column_index,
+                                                         gint      *columns);
+G_GNUC_INTERNAL void murrine_option_menu_get_props (GtkWidget      *widget,
+                                                    GtkRequisition *indicator_size,
+                                                    GtkBorder      *indicator_spacing);
+G_GNUC_INTERNAL MurrineStepper murrine_scrollbar_get_stepper (GtkWidget *widget, GdkRectangle *stepper);
+G_GNUC_INTERNAL MurrineStepper murrine_scrollbar_visible_steppers (GtkWidget *widget);
+G_GNUC_INTERNAL MurrineJunction murrine_scrollbar_get_junction (GtkWidget *widget);
+G_GNUC_INTERNAL gboolean murrine_is_panel_widget (GtkWidget *widget);
+G_GNUC_INTERNAL void murrine_set_toolbar_parameters (ToolbarParameters *toolbar,
+                                                     GtkWidget *widget,
+                                                     GdkWindow *window,
+                                                     gint x, gint y);
+G_GNUC_INTERNAL void murrine_get_notebook_tab_position (GtkWidget *widget,
+                                                        gboolean  *start,
+                                                        gboolean  *end);
+
+#endif /* SUPPORT_H */



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]