]> Pileus Git - ~andy/gtk/blobdiff - modules/engines/ms-windows/msw_style.c
win32: Fall back to raleigh with the classic theme
[~andy/gtk] / modules / engines / ms-windows / msw_style.c
index 589633f57169d697b160618503d6a6d45ac40129..f8a95227bc0fe5cea7bec0fedfc9f933faaada2c 100755 (executable)
@@ -16,9 +16,7 @@
  * 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.
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
  */
 
 /*
@@ -30,6 +28,9 @@
  *  http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdi/pantdraw_4b3g.asp
  */
 
+/* Include first, else we get redefinition warnings about STRICT */
+#include "pango/pangowin32.h"
+
 #include "msw_style.h"
 #include "xp_theme.h"
 
 #include <stdio.h>
 
 #include "gtk/gtk.h"
-
-#include <pango/pangowin32.h>
+#include "gtk/gtk.h"
+#ifndef GTK_COMPILATION
+#define GTK_COMPILATION
+#endif
+#include "gtk/gtkmenushellprivate.h"
 
 #ifdef BUILDING_STANDALONE
 #include "gdk/gdkwin32.h"
 #include "gdk/win32/gdkwin32.h"
 #endif
 
-static HDC get_window_dc (GtkStyle *style, GdkWindow *window,
-                         GtkStateType state_type, gint x, gint y, gint width,
-                         gint height, RECT *rect);
-static void release_window_dc (GtkStyle *style, GdkWindow *window,
-                              GtkStateType state_type);
-
 
 /* Default values, not normally used
  */
@@ -86,81 +84,137 @@ typedef enum
 
 #define PART_SIZE 13
 
-static const guint8 check_aa_bits[] = {
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+static const unsigned char check_aa_bits[] = {
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00
 };
-static const guint8 check_base_bits[] = {
-  0x00, 0x00, 0x00, 0x00, 0xfc, 0x07, 0xfc, 0x07, 0xfc, 0x07, 0xfc, 0x07,
-  0xfc, 0x07, 0xfc,
-  0x07, 0xfc, 0x07, 0xfc, 0x07, 0xfc, 0x07, 0x00, 0x00, 0x00, 0x00
+static const unsigned char check_base_bits[] = {
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0xfc, 0x07, 0x00, 0x00, 0xfc, 0x07, 0x00, 0x00,
+  0xfc, 0x07, 0x00, 0x00, 0xfc, 0x07, 0x00, 0x00,
+  0xfc, 0x07, 0x00, 0x00, 0xfc, 0x07, 0x00, 0x00,
+  0xfc, 0x07, 0x00, 0x00, 0xfc, 0x07, 0x00, 0x00,
+  0xfc, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00
 };
-static const guint8 check_black_bits[] = {
-  0x00, 0x00, 0xfe, 0x0f, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
-  0x02, 0x00, 0x02,
-  0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00
+static const unsigned char check_black_bits[] = {
+  0x00, 0x00, 0x00, 0x00, 0xfe, 0x0f, 0x00, 0x00,
+  0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+  0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+  0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+  0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+  0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00
 };
-static const guint8 check_dark_bits[] = {
-  0xff, 0x1f, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
-  0x01, 0x00, 0x01,
-  0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00
+static const unsigned char check_dark_bits[] = {
+  0xff, 0x1f, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+  0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+  0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+  0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+  0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+  0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+  0x01, 0x00, 0x00, 0x00
 };
-static const guint8 check_light_bits[] = {
-  0x00, 0x00, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10,
-  0x00, 0x10, 0x00,
-  0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0xfe, 0x1f
+static const unsigned char check_light_bits[] = {
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,
+  0x00, 0x10, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,
+  0x00, 0x10, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,
+  0x00, 0x10, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,
+  0x00, 0x10, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,
+  0x00, 0x10, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,
+  0xfe, 0x1f, 0x00, 0x00
 };
-static const guint8 check_mid_bits[] = {
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08,
-  0x00, 0x08, 0x00,
-  0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0xfc, 0x0f, 0x00, 0x00
+static const unsigned char check_mid_bits[] = {
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00,
+  0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00,
+  0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00,
+  0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00,
+  0x00, 0x08, 0x00, 0x00, 0xfc, 0x0f, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00
 };
-static const guint8 check_text_bits[] = {
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x03, 0x88, 0x03,
-  0xd8, 0x01, 0xf8,
-  0x00, 0x70, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+static const unsigned char check_text_bits[] = {
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
+  0x00, 0x03, 0x00, 0x00, 0x88, 0x03, 0x00, 0x00,
+  0xd8, 0x01, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00,
+  0x70, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00
 };
-static const char check_inconsistent_bits[] = {
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0xf0, 0x03, 0xf0,
-  0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+static const unsigned char check_inconsistent_bits[] = {
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0xf0, 0x03, 0x00, 0x00, 0xf0, 0x03, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00
 };
-static const guint8 radio_base_bits[] = {
-  0x00, 0x00, 0x00, 0x00, 0xf0, 0x01, 0xf8, 0x03, 0xfc, 0x07, 0xfc, 0x07,
-  0xfc, 0x07, 0xfc,
-  0x07, 0xfc, 0x07, 0xf8, 0x03, 0xf0, 0x01, 0x00, 0x00, 0x00, 0x00
+static const unsigned char radio_base_bits[] = {
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0xf0, 0x01, 0x00, 0x00, 0xf8, 0x03, 0x00, 0x00,
+  0xfc, 0x07, 0x00, 0x00, 0xfc, 0x07, 0x00, 0x00,
+  0xfc, 0x07, 0x00, 0x00, 0xfc, 0x07, 0x00, 0x00,
+  0xfc, 0x07, 0x00, 0x00, 0xf8, 0x03, 0x00, 0x00,
+  0xf0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00
 };
-static const guint8 radio_black_bits[] = {
-  0x00, 0x00, 0xf0, 0x01, 0x0c, 0x02, 0x04, 0x00, 0x02, 0x00, 0x02, 0x00,
-  0x02, 0x00, 0x02,
-  0x00, 0x02, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+static const unsigned char radio_black_bits[] = {
+  0x00, 0x00, 0x00, 0x00, 0xf0, 0x01, 0x00, 0x00,
+  0x0c, 0x02, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+  0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+  0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+  0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00
 };
-static const guint8 radio_dark_bits[] = {
-  0xf0, 0x01, 0x0c, 0x06, 0x02, 0x00, 0x02, 0x00, 0x01, 0x00, 0x01, 0x00,
-  0x01, 0x00, 0x01,
-  0x00, 0x01, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00
+static const unsigned char radio_dark_bits[] = {
+  0xf0, 0x01, 0x00, 0x00, 0x0c, 0x06, 0x00, 0x00,
+  0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+  0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+  0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+  0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+  0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00
 };
-static const guint8 radio_light_bits[] = {
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x08, 0x00, 0x10, 0x00, 0x10,
-  0x00, 0x10, 0x00,
-  0x10, 0x00, 0x10, 0x00, 0x08, 0x00, 0x08, 0x0c, 0x06, 0xf0, 0x01
+static const unsigned char radio_light_bits[] = {
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00,
+  0x00, 0x10, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,
+  0x00, 0x10, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,
+  0x00, 0x10, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00,
+  0x00, 0x08, 0x00, 0x00, 0x0c, 0x06, 0x00, 0x00,
+  0xf0, 0x01, 0x00, 0x00
 };
-static const guint8 radio_mid_bits[] = {
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x04, 0x00, 0x08, 0x00, 0x08,
-  0x00, 0x08, 0x00,
-  0x08, 0x00, 0x08, 0x00, 0x04, 0x0c, 0x06, 0xf0, 0x01, 0x00, 0x00
+static const unsigned char radio_mid_bits[] = {
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00,
+  0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00,
+  0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00,
+  0x00, 0x08, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00,
+  0x0c, 0x06, 0x00, 0x00, 0xf0, 0x01, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00
 };
-static const guint8 radio_text_bits[] = {
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0xf0, 0x01,
-  0xf0, 0x01, 0xf0,
-  0x01, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+static const unsigned char radio_text_bits[] = {
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0xe0, 0x00, 0x00, 0x00, 0xf0, 0x01, 0x00, 0x00,
+  0xf0, 0x01, 0x00, 0x00, 0xf0, 0x01, 0x00, 0x00,
+  0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00
 };
 
 static struct
 {
-  const guint8 *bits;
-  GdkBitmap *bmap;
+  const unsigned char *bits;
+  cairo_surface_t *bmap;
 } parts[] = {
   { check_aa_bits, NULL           },
   { check_base_bits, NULL         },
@@ -178,27 +232,80 @@ static struct
   { radio_text_bits, NULL         }
 };
 
+static void
+_cairo_draw_line (cairo_t  *cr,
+                  GdkColor *color,
+                  gint      x1,
+                  gint      y1,
+                  gint      x2,
+                  gint      y2)
+{
+  cairo_save (cr);
+
+  gdk_cairo_set_source_color (cr, color);
+  cairo_set_line_cap (cr, CAIRO_LINE_CAP_SQUARE);
+  cairo_set_line_width (cr, 1.0);
+
+  cairo_move_to (cr, x1 + 0.5, y1 + 0.5);
+  cairo_line_to (cr, x2 + 0.5, y2 + 0.5);
+  cairo_stroke (cr);
+
+  cairo_restore (cr);
+}
+
+static void
+_cairo_draw_rectangle (cairo_t *cr,
+                       GdkColor *color,
+                       gboolean filled,
+                       gint x,
+                       gint y,
+                       gint width,
+                       gint height)
+{
+  gdk_cairo_set_source_color (cr, color);
+
+  if (filled)
+    {
+      cairo_rectangle (cr, x, y, width, height);
+      cairo_fill (cr);
+    }
+  else
+    {
+      cairo_rectangle (cr, x + 0.5, y + 0.5, width, height);
+      cairo_stroke (cr);
+    }
+}
+
 static gboolean
-get_system_font (XpThemeClass klazz, XpThemeFont type, LOGFONTA *out_lf)
+get_system_font (XpThemeClass klazz, XpThemeFont type, LOGFONTW *out_lf)
 {
-  NONCLIENTMETRICS ncm;
-  
-  ncm.cbSize = sizeof (NONCLIENTMETRICS);
-  
-  if (SystemParametersInfo (SPI_GETNONCLIENTMETRICS,
-                           sizeof (NONCLIENTMETRICS), &ncm, 0))
-    {
-      if (type == XP_THEME_FONT_CAPTION)
-       *out_lf = ncm.lfCaptionFont;
-      else if (type == XP_THEME_FONT_MENU)
-       *out_lf = ncm.lfMenuFont;
-      else if (type == XP_THEME_FONT_STATUS)
-       *out_lf = ncm.lfStatusFont;
-      else
-       *out_lf = ncm.lfMessageFont;
-      
+  if (xp_theme_get_system_font (klazz, type, out_lf))
+    {
       return TRUE;
     }
+  else
+    {
+      /* Use wide char versions here, as the theming functions only support
+       * wide chars versions of the structures. */
+      NONCLIENTMETRICSW ncm;
+
+      ncm.cbSize = sizeof (NONCLIENTMETRICSW);
+
+      if (SystemParametersInfoW (SPI_GETNONCLIENTMETRICS,
+                               sizeof (NONCLIENTMETRICSW), &ncm, 0))
+       {
+         if (type == XP_THEME_FONT_CAPTION)
+           *out_lf = ncm.lfCaptionFont;
+         else if (type == XP_THEME_FONT_MENU)
+           *out_lf = ncm.lfMenuFont;
+         else if (type == XP_THEME_FONT_STATUS)
+           *out_lf = ncm.lfStatusFont;
+         else
+           *out_lf = ncm.lfMessageFont;
+
+         return TRUE;
+       }
+    }
 
   return FALSE;
 }
@@ -207,27 +314,54 @@ static char *
 sys_font_to_pango_font (XpThemeClass klazz, XpThemeFont type, char *buf,
                        size_t bufsiz)
 {
-  LOGFONTW lfw;
-  LOGFONTA lfa;
-  PangoFontDescription* pfd = NULL;
+  LOGFONTW lf;
 
-  if (xp_theme_get_system_font (klazz, type, &lfw))
-    {
-      pfd = pango_win32_font_description_from_logfontw(&lfw);
-    }
-  else if (get_system_font (klazz, type, &lfa))
+  if (get_system_font (klazz, type, &lf))
     {
-      pfd = pango_win32_font_description_from_logfont(&lfa);
-    }
+      PangoFontDescription *desc = NULL;
+      int pt_size;
+      const char *font;
 
-  if (pfd)
-    {
-      char *s;
+      desc = pango_win32_font_description_from_logfontw (&lf);
+      if (!desc)
+       return NULL;
+
+      font = pango_font_description_to_string (desc);
+      pt_size = pango_font_description_get_size (desc);
+
+      if (!(font && *font))
+       {
+         pango_font_description_free (desc);
+         return NULL;
+       }
+
+      if (pt_size == 0)
+       {
+         HDC hDC;
+         HWND hwnd;
+
+         hwnd = GetDesktopWindow ();
+         hDC = GetDC (hwnd);
+
+         if (hDC)
+           pt_size = -MulDiv (lf.lfHeight, 72, GetDeviceCaps (hDC, LOGPIXELSY));
+         else
+           pt_size = 10;
 
-      s = pango_font_description_to_string(pfd);
-      pango_font_description_free(pfd);
+         if (hDC)
+           ReleaseDC (hwnd, hDC);
 
-      return s;
+         g_snprintf (buf, bufsiz, "%s %d", font, pt_size);
+       }
+      else
+       {
+         g_snprintf (buf, bufsiz, "%s", font);
+       }
+
+      if (desc)
+       pango_font_description_free (desc);
+
+      return buf;
     }
 
   return NULL;
@@ -243,29 +377,41 @@ sys_font_to_pango_font (XpThemeClass klazz, XpThemeFont type, char *buf,
    for now */
 #define XP_THEME_CLASS_TEXT XP_THEME_CLASS_BUTTON
 
-static void
-setup_menu_settings (GtkSettings *settings)
+#define WIN95_VERSION   0x400
+#define WIN2K_VERSION   0x500
+#define WINXP_VERSION   0x501
+#define WIN2K3_VERSION  0x502
+#define VISTA_VERSION   0x600
+
+static gint32
+get_windows_version ()
 {
-  int menu_delay;
-  gboolean win95 = FALSE;
-  OSVERSIONINFOEX osvi;
-  GObjectClass *klazz = G_OBJECT_GET_CLASS (G_OBJECT (settings));
+  static gint32 version = 0;
+  static gboolean have_version = FALSE;
 
-  ZeroMemory (&osvi, sizeof (OSVERSIONINFOEX));
-  osvi.dwOSVersionInfoSize = sizeof (OSVERSIONINFOEX);
+  if (!have_version)
+    {
+      OSVERSIONINFOEX osvi;
+      have_version = TRUE;
 
-  if (!GetVersionEx ((OSVERSIONINFO *) & osvi))
-    win95 = TRUE;              /* assume the worst */
+      ZeroMemory (&osvi, sizeof (OSVERSIONINFOEX));
+      osvi.dwOSVersionInfoSize = sizeof (OSVERSIONINFOEX);
 
-  if (osvi.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS)
-    {
-      if (osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 0)
-       {
-         win95 = TRUE;
-       }
+      GetVersionEx((OSVERSIONINFO*) &osvi);
+
+      version = (osvi.dwMajorVersion & 0xff) << 8 | (osvi.dwMinorVersion & 0xff);
     }
 
-  if (!win95)
+  return version;
+}
+
+static void
+setup_menu_settings (GtkSettings *settings)
+{
+  int menu_delay;
+  GObjectClass *klazz = G_OBJECT_GET_CLASS (G_OBJECT (settings));
+
+  if (get_windows_version () > WIN95_VERSION)
     {
       if (SystemParametersInfo (SPI_GETMENUSHOWDELAY, 0, &menu_delay, 0))
        {
@@ -323,7 +469,7 @@ msw_style_setup_system_settings (void)
   setup_menu_settings (settings);
 
   /*
-     http://developer.gnome.org/doc/API/2.0/gtk/GtkSettings.html
+     http://library.gnome.org/devel/gtk/stable/GtkSettings.html
      http://msdn.microsoft.com/library/default.asp?url=/library/en-us/sysinfo/base/systemparametersinfo.asp
      http://msdn.microsoft.com/library/default.asp?url=/library/en-us/sysinfo/base/getsystemmetrics.asp */
 }
@@ -392,7 +538,8 @@ setup_msw_rc_style (void)
   GdkColor text_prelight;
 
   /* Prelight */
-  sys_color_to_gtk_color (XP_THEME_CLASS_TEXT, COLOR_HIGHLIGHTTEXT,
+  sys_color_to_gtk_color (get_windows_version () >= VISTA_VERSION ? XP_THEME_CLASS_MENU : XP_THEME_CLASS_TEXT,
+                         get_windows_version () >= VISTA_VERSION ? COLOR_MENUTEXT : COLOR_HIGHLIGHTTEXT,
                          &fg_prelight);
   sys_color_to_gtk_color (XP_THEME_CLASS_TEXT, COLOR_HIGHLIGHT, &bg_prelight);
   sys_color_to_gtk_color (XP_THEME_CLASS_TEXT, COLOR_HIGHLIGHT,
@@ -488,7 +635,8 @@ setup_msw_rc_style (void)
   g_snprintf (buf, sizeof (buf),
              "style \"msw-tooltips-caption\" = \"msw-default\"\n"
              "{fg[NORMAL] = { %d, %d, %d }\n" "%s = \"%s\"\n"
-             "}widget \"gtk-tooltips.GtkLabel\" style \"msw-tooltips-caption\"\n",
+             "}widget \"gtk-tooltips.GtkLabel\" style \"msw-tooltips-caption\"\n"
+             "widget \"gtk-tooltip.GtkLabel\" style \"msw-tooltips-caption\"\n",
              tooltip_fore.red, tooltip_fore.green, tooltip_fore.blue,
              (font_ptr ? "font_name" : "#"),
              (font_ptr ? font_ptr : " font name should go here"));
@@ -497,7 +645,8 @@ setup_msw_rc_style (void)
   g_snprintf (buf, sizeof (buf),
              "style \"msw-tooltips\" = \"msw-default\"\n"
              "{bg[NORMAL] = { %d, %d, %d }\n"
-             "}widget \"gtk-tooltips*\" style \"msw-tooltips\"\n",
+             "}widget \"gtk-tooltips*\" style \"msw-tooltips\"\n"
+             "widget \"gtk-tooltip*\" style \"msw-tooltips\"\n",
              tooltip_back.red, tooltip_back.green, tooltip_back.blue);
   gtk_rc_parse_string (buf);
 
@@ -513,8 +662,9 @@ setup_msw_rc_style (void)
              btn_face.red, btn_face.green, btn_face.blue);
   gtk_rc_parse_string (buf);
 
-  /* enable coloring for text on buttons TODO: use GetThemeMetric for the
-     border and outside border */
+  /* enable coloring for text on buttons
+   * TODO: use GetThemeMetric for the border and outside border
+   * TODO: child-displacement-x & y should be 0 when XP theme is active */
   g_snprintf (buf, sizeof (buf),
              "style \"msw-button\" = \"msw-default\"\n"
              "{\n"
@@ -702,7 +852,7 @@ setup_system_styles (GtkStyle *style)
   sys_color_to_gtk_color (XP_THEME_CLASS_TEXT, COLOR_GRAYTEXT,
                          &style->fg[GTK_STATE_INSENSITIVE]);
   sys_color_to_gtk_color (XP_THEME_CLASS_BUTTON, COLOR_BTNTEXT,
-                         &style->fg[GTK_STATE_ACTIVE]);
+                          &style->fg[GTK_STATE_ACTIVE]);
   sys_color_to_gtk_color (XP_THEME_CLASS_WINDOW, COLOR_WINDOWTEXT,
                          &style->fg[GTK_STATE_PRELIGHT]);
 
@@ -726,37 +876,14 @@ setup_system_styles (GtkStyle *style)
     }
 }
 
-static gboolean
-sanitize_size (GdkWindow *window, gint *width, gint *height)
-{
-  gboolean set_bg = FALSE;
-
-  if ((*width == -1) && (*height == -1))
-    {
-      set_bg = GDK_IS_WINDOW (window);
-      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);
-    }
-
-  return set_bg;
-}
-
 static XpThemeElement
 map_gtk_progress_bar_to_xp (GtkProgressBar *progress_bar, gboolean trough)
 {
   XpThemeElement ret;
 
-  switch (progress_bar->orientation)
+  switch (gtk_orientable_get_orientation (GTK_ORIENTABLE (progress_bar)))
     {
-    case GTK_PROGRESS_LEFT_TO_RIGHT:
-    case GTK_PROGRESS_RIGHT_TO_LEFT:
+    case GTK_ORIENTATION_HORIZONTAL:
       ret = trough
        ? XP_THEME_ELEMENT_PROGRESS_TROUGH_H
        : XP_THEME_ELEMENT_PROGRESS_BAR_H;
@@ -780,7 +907,7 @@ is_combo_box_child (GtkWidget *w)
   if (w == NULL)
     return FALSE;
 
-  for (tmp = w->parent; tmp; tmp = tmp->parent)
+  for (tmp = gtk_widget_get_parent (w); tmp; tmp = gtk_widget_get_parent (tmp))
     {
       if (GTK_IS_COMBO_BOX (tmp))
        return TRUE;
@@ -792,9 +919,9 @@ is_combo_box_child (GtkWidget *w)
 /* This function is not needed anymore */
 /* static gboolean
 combo_box_draw_arrow (GtkStyle *style,
-                     GdkWindow *window,
+                     cairo_t *cr,
                      GtkStateType state,
-                     GdkRectangle *area, GtkWidget *widget)
+                     GtkWidget *widget)
 {
   if (xp_theme_is_active ())
     return TRUE;
@@ -804,16 +931,17 @@ combo_box_draw_arrow (GtkStyle *style,
       DWORD border;
       RECT rect;
       HDC dc;
+      XpDCInfo dc_info;
 
-      dc = get_window_dc (style, window, state, area->x, area->y, area->width,
+      dc = get_window_dc (style, cr, state, &dc_info, area->x, area->y, area->width,
                          area->height, &rect);
-      border = (GTK_TOGGLE_BUTTON (widget->parent)->
+      border = (GTK_TOGGLE_BUTTON (gtk_widget_get_parent (widget))->
                active ? DFCS_PUSHED | DFCS_FLAT : 0);
 
       InflateRect (&rect, 1, 1);
       DrawFrameControl (dc, &rect, DFC_SCROLL, DFCS_SCROLLDOWN | border);
 
-      release_window_dc (style, window, state);
+      release_window_dc (&dc_info);
 
       return TRUE;
     }
@@ -822,37 +950,25 @@ combo_box_draw_arrow (GtkStyle *style,
 }*/
 
 static void
-draw_part (GdkDrawable *drawable,
-          GdkGC *gc, GdkRectangle *area, gint x, gint y, Part part)
+draw_part (cairo_t *cr,
+           GdkColor *gc, gint x, gint y, Part part)
 {
-  if (area)
-    gdk_gc_set_clip_rectangle (gc, area);
-
   if (!parts[part].bmap)
     {
-      parts[part].bmap = gdk_bitmap_create_from_data (drawable,
-                                                     parts[part].bits,
-                                                     PART_SIZE, PART_SIZE);
+      parts[part].bmap = cairo_image_surface_create_for_data ((unsigned char *)parts[part].bits,
+                                                             CAIRO_FORMAT_A1,
+                                                             PART_SIZE, PART_SIZE, 4);
     }
 
-  gdk_gc_set_ts_origin (gc, x, y);
-  gdk_gc_set_stipple (gc, parts[part].bmap);
-  gdk_gc_set_fill (gc, GDK_STIPPLED);
-
-  gdk_draw_rectangle (drawable, gc, TRUE, x, y, PART_SIZE, PART_SIZE);
-
-  gdk_gc_set_fill (gc, GDK_SOLID);
-
-  if (area)
-    gdk_gc_set_clip_rectangle (gc, NULL);
+  gdk_cairo_set_source_color (cr, gc);
+  cairo_mask_surface (cr, parts[part].bmap, x, y);
 }
 
 static void
 draw_check (GtkStyle *style,
-           GdkWindow *window,
+           cairo_t *cr,
            GtkStateType state,
            GtkShadowType shadow,
-           GdkRectangle *area,
            GtkWidget *widget,
            const gchar *detail, gint x, gint y, gint width, gint height)
 {
@@ -863,8 +979,8 @@ draw_check (GtkStyle *style,
     {
       if (shadow == GTK_SHADOW_IN)
        {
-         draw_part (window, style->black_gc, area, x, y, CHECK_TEXT);
-         draw_part (window, style->dark_gc[state], area, x, y, CHECK_AA);
+          draw_part (cr, &style->black, x, y, CHECK_TEXT);
+          draw_part (cr, &style->dark[state], x, y, CHECK_AA);
        }
     }
   else
@@ -884,31 +1000,27 @@ draw_check (GtkStyle *style,
          break;
        }
 
-      if (!xp_theme_draw (window, theme_elt,
-                         style, x, y, width, height, state, area))
+      if (!xp_theme_draw (cr, theme_elt,
+                         style, x, y, width, height, state))
        {
          if (detail && !strcmp (detail, "cellcheck"))
            state = GTK_STATE_NORMAL;
 
-         draw_part (window, style->black_gc, area, x, y, CHECK_BLACK);
-         draw_part (window, style->dark_gc[state], area, x, y, CHECK_DARK);
-         draw_part (window, style->mid_gc[state], area, x, y, CHECK_MID);
-         draw_part (window, style->light_gc[state], area, x, y, CHECK_LIGHT);
-         draw_part (window, style->base_gc[state], area, x, y, CHECK_BASE);
+          draw_part (cr, &style->black, x, y, CHECK_BLACK);
+          draw_part (cr, &style->dark[state], x, y, CHECK_DARK);
+          draw_part (cr, &style->mid[state], x, y, CHECK_MID);
+          draw_part (cr, &style->light[state], x, y, CHECK_LIGHT);
+          draw_part (cr, &style->base[state], x, y, CHECK_BASE);
 
          if (shadow == GTK_SHADOW_IN)
            {
-             draw_part (window, style->text_gc[state], area, x,
-                        y, CHECK_TEXT);
-             draw_part (window, style->text_aa_gc[state], area,
-                        x, y, CHECK_AA);
+              draw_part (cr, &style->text[state], x, y, CHECK_TEXT);
+              draw_part (cr, &style->text_aa[state], x, y, CHECK_AA);
            }
          else if (shadow == GTK_SHADOW_ETCHED_IN)
            {
-             draw_part (window, style->text_gc[state], area, x, y,
-                        CHECK_INCONSISTENT);
-             draw_part (window, style->text_aa_gc[state], area, x, y,
-                        CHECK_AA);
+              draw_part (cr, &style->text[state], x, y, CHECK_INCONSISTENT);
+              draw_part (cr, &style->text_aa[state], x, y, CHECK_AA);
            }
        }
     }
@@ -916,9 +1028,8 @@ draw_check (GtkStyle *style,
 
 static void
 draw_expander (GtkStyle *style,
-              GdkWindow *window,
+              cairo_t *cr,
               GtkStateType state,
-              GdkRectangle *area,
               GtkWidget *widget,
               const gchar *detail,
               gint x, gint y, GtkExpanderStyle expander_style)
@@ -947,22 +1058,24 @@ draw_expander (GtkStyle *style,
   if (expander_size > 2)
     expander_size -= 2;
 
-  if (area)
-    gdk_gc_set_clip_rectangle (style->fg_gc[state], area);
+/* FIXME: wtf?
+      gdk_cairo_set_source_color (cr, &style->fg[state]);
+ */
 
   expander_semi_size = expander_size / 2;
   x -= expander_semi_size;
   y -= expander_semi_size;
 
-  if (!xp_theme_draw (window, xp_expander, style,
-                     x, y, expander_size, expander_size, state, area))
+  if (!xp_theme_draw (cr, xp_expander, style,
+                     x, y, expander_size, expander_size, state))
     {
       HDC dc;
       RECT rect;
       HPEN pen;
       HGDIOBJ old_pen;
+      XpDCInfo dc_info;
 
-      dc = get_window_dc (style, window, state, x, y, expander_size,
+      dc = get_window_dc (style, cr, state, &dc_info, x, y, expander_size,
                          expander_size, &rect);
       FrameRect (dc, &rect, GetSysColorBrush (COLOR_GRAYTEXT));
       InflateRect (&rect, -1, -1);
@@ -988,19 +1101,15 @@ draw_expander (GtkStyle *style,
 
       SelectObject (dc, old_pen);
       DeleteObject (pen);
-      release_window_dc (style, window, state);
+      release_window_dc (&dc_info);
     }
-
-  if (area)
-    gdk_gc_set_clip_rectangle (style->fg_gc[state], NULL);
 }
 
 static void
 draw_option (GtkStyle *style,
-            GdkWindow *window,
+            cairo_t *cr,
             GtkStateType state,
             GtkShadowType shadow,
-            GdkRectangle *area,
             GtkWidget *widget,
             const gchar *detail, gint x, gint y, gint width, gint height)
 {
@@ -1011,15 +1120,15 @@ draw_option (GtkStyle *style,
     {
       if (shadow == GTK_SHADOW_IN)
        {
-         draw_part (window, style->fg_gc[state], area, x, y, RADIO_TEXT);
+          draw_part (cr, &style->fg[state], x, y, RADIO_TEXT);
        }
     }
   else
     {
-      if (xp_theme_draw (window, shadow == GTK_SHADOW_IN
+      if (xp_theme_draw (cr, shadow == GTK_SHADOW_IN
                         ? XP_THEME_ELEMENT_PRESSED_RADIO_BUTTON
                         : XP_THEME_ELEMENT_RADIO_BUTTON,
-                        style, x, y, width, height, state, area))
+                        style, x, y, width, height, state))
        {
        }
       else
@@ -1027,32 +1136,28 @@ draw_option (GtkStyle *style,
          if (detail && !strcmp (detail, "cellradio"))
            state = GTK_STATE_NORMAL;
 
-         draw_part (window, style->black_gc, area, x, y, RADIO_BLACK);
-         draw_part (window, style->dark_gc[state], area, x, y, RADIO_DARK);
-         draw_part (window, style->mid_gc[state], area, x, y, RADIO_MID);
-         draw_part (window, style->light_gc[state], area, x, y, RADIO_LIGHT);
-         draw_part (window, style->base_gc[state], area, x, y, RADIO_BASE);
+          draw_part (cr, &style->black, x, y, RADIO_BLACK);
+          draw_part (cr, &style->dark[state], x, y, RADIO_DARK);
+          draw_part (cr, &style->mid[state], x, y, RADIO_MID);
+          draw_part (cr, &style->light[state], x, y, RADIO_LIGHT);
+          draw_part (cr, &style->base[state], x, y, RADIO_BASE);
 
          if (shadow == GTK_SHADOW_IN)
-           draw_part (window, style->text_gc[state], area, x, y, RADIO_TEXT);
+            draw_part (cr, &style->text[state], x, y, RADIO_TEXT);
        }
     }
 }
 
 static void
-draw_varrow (GdkWindow *window,
-            GdkGC *gc,
+draw_varrow (cairo_t *cr,
+             GdkColor *gc,
             GtkShadowType shadow_type,
-            GdkRectangle *area,
             GtkArrowType arrow_type, gint x, gint y, gint width, gint height)
 {
   gint steps, extra;
   gint y_start, y_increment;
   gint i;
 
-  if (area)
-    gdk_gc_set_clip_rectangle (gc, area);
-
   width = width + width % 2 - 1;       /* Force odd */
   steps = 1 + width / 2;
   extra = height - steps;
@@ -1070,29 +1175,22 @@ draw_varrow (GdkWindow *window,
 
   for (i = extra; i < height; i++)
     {
-      gdk_draw_line (window, gc,
+      _cairo_draw_line (cr, gc,
                     x + (i - extra), y_start + i * y_increment,
                     x + width - (i - extra) - 1, y_start + i * y_increment);
     }
-
-  if (area)
-    gdk_gc_set_clip_rectangle (gc, NULL);
 }
 
 static void
-draw_harrow (GdkWindow *window,
-            GdkGC *gc,
+draw_harrow (cairo_t *cr,
+             GdkColor *gc,
             GtkShadowType shadow_type,
-            GdkRectangle *area,
             GtkArrowType arrow_type, gint x, gint y, gint width, gint height)
 {
   gint steps, extra;
   gint x_start, x_increment;
   gint i;
 
-  if (area)
-    gdk_gc_set_clip_rectangle (gc, area);
-
   height = height + height % 2 - 1;    /* Force odd */
   steps = 1 + height / 2;
   extra = width - steps;
@@ -1110,14 +1208,10 @@ draw_harrow (GdkWindow *window,
 
   for (i = extra; i < width; i++)
     {
-      gdk_draw_line (window, gc,
+      _cairo_draw_line (cr, gc,
                     x_start + i * x_increment, y + (i - extra),
                     x_start + i * x_increment, y + height - (i - extra) - 1);
     }
-
-
-  if (area)
-    gdk_gc_set_clip_rectangle (gc, NULL);
 }
 
 /* This function makes up for some brokeness in gtkrange.c
@@ -1189,10 +1283,9 @@ to_xp_arrow (GtkArrowType arrow_type)
 
 static void
 draw_arrow (GtkStyle *style,
-           GdkWindow *window,
+           cairo_t *cr,
            GtkStateType state,
            GtkShadowType shadow,
-           GdkRectangle *area,
            GtkWidget *widget,
            const gchar *detail,
            GtkArrowType arrow_type,
@@ -1201,11 +1294,10 @@ draw_arrow (GtkStyle *style,
   const gchar *name;
   HDC dc;
   RECT rect;
+  XpDCInfo dc_info;
 
   name = gtk_widget_get_name (widget);
 
-  sanitize_size (window, &width, &height);
-
   if (GTK_IS_ARROW (widget) && is_combo_box_child (widget) && xp_theme_is_active ())
     return;
 
@@ -1228,7 +1320,7 @@ draw_arrow (GtkStyle *style,
          ++y;
        }
 
-      draw_varrow (window, style->fg_gc[state], shadow, area,
+      draw_varrow (cr, &style->fg[state], shadow,
                   arrow_type, x, y, width, height);
 
       return;
@@ -1248,15 +1340,15 @@ draw_arrow (GtkStyle *style,
       reverse_engineer_stepper_box (widget, arrow_type,
                                    &box_x, &box_y, &box_width, &box_height);
 
-      if (scrollbar->range.adjustment->page_size >=
-         (scrollbar->range.adjustment->upper -
-          scrollbar->range.adjustment->lower))
+      if (gtk_adjustment_get_page_size(gtk_range_get_adjustment(&scrollbar->range)) >=
+          (gtk_adjustment_get_upper(gtk_range_get_adjustment(&scrollbar->range)) -
+           gtk_adjustment_get_lower(gtk_range_get_adjustment(&scrollbar->range))))
        {
          is_disabled = TRUE;
        }
 
-      if (xp_theme_draw (window, to_xp_arrow (arrow_type), style, box_x, box_y,
-                        box_width, box_height, state, area))
+      if (xp_theme_draw (cr, to_xp_arrow (arrow_type), style, box_x, box_y,
+                        box_width, box_height, state))
        {
        }
       else
@@ -1290,15 +1382,13 @@ draw_arrow (GtkStyle *style,
 
          if (widget)
            {
-             sanitize_size (window, &width, &height);
-
-             dc = get_window_dc (style, window, state,
+             dc = get_window_dc (style, cr, state, &dc_info,
                                  box_x, box_y, box_width, box_height, &rect);
              DrawFrameControl (dc, &rect, DFC_SCROLL,
                                btn_type | (shadow ==
                                            GTK_SHADOW_IN ? (DFCS_PUSHED |
                                                             DFCS_FLAT) : 0));
-             release_window_dc (style, window, state);
+             release_window_dc (&dc_info);
            }
        }
     }
@@ -1308,20 +1398,23 @@ draw_arrow (GtkStyle *style,
       if (name && !strcmp (name, "gtk-toolbar-arrow"))
        {
          if (xp_theme_draw
-             (window, XP_THEME_ELEMENT_REBAR_CHEVRON, style, x, y,
-              width, height, state, area))
+             (cr, XP_THEME_ELEMENT_REBAR_CHEVRON, style, x, y,
+              width, height, state))
            {
              return;
            }
        }
       /* probably a gtk combo box on a toolbar */
-      else if (0               /* widget->parent && GTK_IS_BUTTON
-                                  (widget->parent) */ )
+      else if (0               /* gtk_widget_get_parent (widget) && GTK_IS_BUTTON
+                                  (gtk_widget_get_parent (widget)) */ )
        {
+         GtkAllocation allocation;
+
+         gtk_widget_get_allocation (widget, &allocation);
          if (xp_theme_draw
-             (window, XP_THEME_ELEMENT_COMBOBUTTON, style, x - 3,
-              widget->allocation.y + 1, width + 5,
-              widget->allocation.height - 4, state, area))
+             (cr, XP_THEME_ELEMENT_COMBOBUTTON, style, x - 3,
+              allocation.y + 1, width + 5,
+              allocation.height - 4, state))
            {
              return;
            }
@@ -1332,7 +1425,7 @@ draw_arrow (GtkStyle *style,
          x += (width - 7) / 2;
          y += (height - 5) / 2;
 
-         draw_varrow (window, style->fg_gc[state], shadow, area,
+          draw_varrow (cr, &style->fg[state], shadow,
                       arrow_type, x, y, 7, 5);
        }
       else
@@ -1340,7 +1433,7 @@ draw_arrow (GtkStyle *style,
          x += (width - 5) / 2;
          y += (height - 7) / 2;
 
-         draw_harrow (window, style->fg_gc[state], shadow, area,
+          draw_harrow (cr, &style->fg[state], shadow,
                       arrow_type, x, y, 5, 7);
        }
     }
@@ -1388,7 +1481,7 @@ is_toolbar_child (GtkWidget *wid)
       if (GTK_IS_TOOLBAR (wid) || GTK_IS_HANDLE_BOX (wid))
        return TRUE;
       else
-       wid = wid->parent;
+       wid = gtk_widget_get_parent (wid);
     }
 
   return FALSE;
@@ -1402,55 +1495,11 @@ is_menu_tool_button_child (GtkWidget *wid)
       if (GTK_IS_MENU_TOOL_BUTTON (wid))
        return TRUE;
       else
-       wid = wid->parent;
+       wid = gtk_widget_get_parent (wid);
     }
   return FALSE;
 }
 
-HDC
-get_window_dc (GtkStyle *style, GdkWindow *window, GtkStateType state_type,
-              gint x, gint y, gint width, gint height, RECT *rect)
-{
-  int xoff, yoff;
-  GdkDrawable *drawable;
-
-  if (!GDK_IS_WINDOW (window))
-    {
-      xoff = 0;
-      yoff = 0;
-      drawable = window;
-    }
-  else
-    {
-      gdk_window_get_internal_paint_info (window, &drawable, &xoff, &yoff);
-    }
-
-  rect->left = x - xoff;
-  rect->top = y - yoff;
-  rect->right = rect->left + width;
-  rect->bottom = rect->top + height;
-
-  return gdk_win32_hdc_get (drawable, style->dark_gc[state_type], 0);
-}
-
-void
-release_window_dc (GtkStyle *style, GdkWindow *window,
-                  GtkStateType state_type)
-{
-  GdkDrawable *drawable;
-
-  if (!GDK_IS_WINDOW (window))
-    {
-      drawable = window;
-    }
-  else
-    {
-      gdk_window_get_internal_paint_info (window, &drawable, NULL, NULL);
-    }
-
-  gdk_win32_hdc_release (drawable, style->dark_gc[state_type], 0);
-}
-
 static HPEN
 get_light_pen ()
 {
@@ -1506,28 +1555,35 @@ draw_3d_border (HDC hdc, RECT *rc, gboolean sunken)
 }
 
 static gboolean
-draw_menu_item (GdkWindow *window, GtkWidget *widget, GtkStyle *style,
+draw_menu_item (cairo_t *cr, GtkWidget *widget, GtkStyle *style,
                gint x, gint y, gint width, gint height,
-               GtkStateType state_type, GdkRectangle *area)
+               GtkStateType state_type)
 {
   GtkWidget *parent;
   GtkMenuShell *bar;
   HDC dc;
   RECT rect;
+  XpDCInfo dc_info;
+
+  if (xp_theme_is_active ())
+    {
+      return (xp_theme_draw (cr, XP_THEME_ELEMENT_MENU_ITEM, style,
+                             x, y, width, height, state_type));
+    }
 
   if ((parent = gtk_widget_get_parent (widget))
       && GTK_IS_MENU_BAR (parent) && !xp_theme_is_active ())
     {
       bar = GTK_MENU_SHELL (parent);
 
-      dc = get_window_dc (style, window, state_type, x, y, width, height, &rect);
+      dc = get_window_dc (style, cr, state_type, &dc_info, x, y, width, height, &rect);
 
       if (state_type == GTK_STATE_PRELIGHT)
        {
-         draw_3d_border (dc, &rect, bar->active);
+        draw_3d_border (dc, &rect, bar->priv->active);
        }
 
-      release_window_dc (style, window, state_type);
+      release_window_dc (&dc_info);
 
       return TRUE;
     }
@@ -1562,18 +1618,19 @@ get_dither_brush (void)
 }
 
 static gboolean
-draw_tool_button (GdkWindow *window, GtkWidget *widget, GtkStyle *style,
+draw_tool_button (cairo_t *cr, GtkWidget *widget, GtkStyle *style,
                  gint x, gint y, gint width, gint height,
-                 GtkStateType state_type, GdkRectangle *area)
+                 GtkStateType state_type)
 {
   HDC dc;
   RECT rect;
+  XpDCInfo dc_info;
   gboolean is_toggled = FALSE;
 
   if (xp_theme_is_active ())
     {
-      return (xp_theme_draw (window, XP_THEME_ELEMENT_TOOLBAR_BUTTON, style,
-                            x, y, width, height, state_type, area));
+      return (xp_theme_draw (cr, XP_THEME_ELEMENT_TOOLBAR_BUTTON, style,
+                            x, y, width, height, state_type));
     }
 
   if (GTK_IS_TOGGLE_BUTTON (widget))
@@ -1590,7 +1647,7 @@ draw_tool_button (GdkWindow *window, GtkWidget *widget, GtkStyle *style,
       return FALSE;
     }
 
-  dc = get_window_dc (style, window, state_type, x, y, width, height, &rect);
+  dc = get_window_dc (style, cr, state_type, &dc_info, x, y, width, height, &rect);
   if (state_type == GTK_STATE_PRELIGHT)
     {
       if (is_toggled)
@@ -1602,7 +1659,7 @@ draw_tool_button (GdkWindow *window, GtkWidget *widget, GtkStyle *style,
     }
   else if (state_type == GTK_STATE_ACTIVE)
     {
-      if (is_toggled && !is_menu_tool_button_child (widget->parent))
+      if (is_toggled && !is_menu_tool_button_child (gtk_widget_get_parent (widget)))
        {
          SetTextColor (dc, GetSysColor (COLOR_3DHILIGHT));
          SetBkColor (dc, GetSysColor (COLOR_BTNFACE));
@@ -1612,20 +1669,21 @@ draw_tool_button (GdkWindow *window, GtkWidget *widget, GtkStyle *style,
       draw_3d_border (dc, &rect, TRUE);
     }
 
-  release_window_dc (style, window, state_type);
+  release_window_dc (&dc_info);
 
   return TRUE;
 }
 
 static void
-draw_push_button (GdkWindow *window, GtkWidget *widget, GtkStyle *style,
+draw_push_button (cairo_t *cr, GtkWidget *widget, GtkStyle *style,
                  gint x, gint y, gint width, gint height,
                  GtkStateType state_type, gboolean is_default)
 {
   HDC dc;
   RECT rect;
+  XpDCInfo dc_info;
 
-  dc = get_window_dc (style, window, state_type, x, y, width, height, &rect);
+  dc = get_window_dc (style, cr, state_type, &dc_info, x, y, width, height, &rect);
 
   if (GTK_IS_TOGGLE_BUTTON (widget))
     {
@@ -1656,7 +1714,7 @@ draw_push_button (GdkWindow *window, GtkWidget *widget, GtkStyle *style,
     }
   else
     {
-      if (is_default || GTK_WIDGET_HAS_FOCUS (widget))
+      if (is_default || gtk_widget_has_focus (widget))
        {
          FrameRect (dc, &rect, GetSysColorBrush (COLOR_WINDOWFRAME));
          InflateRect (&rect, -1, -1);
@@ -1665,43 +1723,43 @@ draw_push_button (GdkWindow *window, GtkWidget *widget, GtkStyle *style,
       DrawFrameControl (dc, &rect, DFC_BUTTON, DFCS_BUTTONPUSH);
     }
 
-  release_window_dc (style, window, state_type);
+  release_window_dc (&dc_info);
 }
 
 static void
 draw_box (GtkStyle *style,
-         GdkWindow *window,
+         cairo_t *cr,
          GtkStateType state_type,
          GtkShadowType shadow_type,
-         GdkRectangle *area,
          GtkWidget *widget,
          const gchar *detail, gint x, gint y, gint width, gint height)
 {
   if (is_combo_box_child (widget) && detail && !strcmp (detail, "button"))
     {
       RECT rect;
+      XpDCInfo dc_info;
       DWORD border;
       HDC dc;
       int cx;
 
-      border = (GTK_TOGGLE_BUTTON (widget)->active ? DFCS_PUSHED | DFCS_FLAT : 0);
+      border = (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget)) ? DFCS_PUSHED | DFCS_FLAT : 0);
 
-      dc = get_window_dc (style, window, state_type, x, y, width, height, &rect);
+      dc = get_window_dc (style, cr, state_type, &dc_info, x, y, width, height, &rect);
       DrawFrameControl (dc, &rect, DFC_SCROLL, DFCS_SCROLLDOWN | border);
-      release_window_dc (style, window, state_type);
+      release_window_dc (&dc_info);
 
       if (xp_theme_is_active ()
-         && xp_theme_draw (window, XP_THEME_ELEMENT_COMBOBUTTON, style, x, y,
-                           width, height, state_type, area))
+         && xp_theme_draw (cr, XP_THEME_ELEMENT_COMBOBUTTON, style, x, y,
+                           width, height, state_type))
        {
       cx = GetSystemMetrics(SM_CXVSCROLL);
       x += width - cx;
       width = cx;
 
 
-      dc = get_window_dc (style, window, state_type, x, y, width - cx, height, &rect);
+      dc = get_window_dc (style, cr, state_type, &dc_info, x, y, width - cx, height, &rect);
       FillRect (dc, &rect, GetSysColorBrush (COLOR_WINDOW));
-      release_window_dc (style, window, state_type);
+      release_window_dc (&dc_info);
       return;
        }
     }
@@ -1709,11 +1767,11 @@ draw_box (GtkStyle *style,
   if (detail &&
       (!strcmp (detail, "button") || !strcmp (detail, "buttondefault")))
     {
-      if (GTK_IS_TREE_VIEW (widget->parent) || GTK_IS_CLIST (widget->parent))
+      if (GTK_IS_TREE_VIEW (gtk_widget_get_parent (widget)))
       {
         if (xp_theme_draw
-             (window, XP_THEME_ELEMENT_LIST_HEADER, style, x, y,
-              width, height, state_type, area))
+             (cr, XP_THEME_ELEMENT_LIST_HEADER, style, x, y,
+              width, height, state_type))
            {
              return;
            }
@@ -1721,38 +1779,39 @@ draw_box (GtkStyle *style,
            {
              HDC dc;
              RECT rect;
-             dc = get_window_dc (style, window, state_type, x, y, width, height, &rect);
+             XpDCInfo dc_info;
+             dc = get_window_dc (style, cr, state_type, &dc_info, x, y, width, height, &rect);
 
              DrawFrameControl (dc, &rect, DFC_BUTTON, DFCS_BUTTONPUSH |
                                (state_type ==
                                 GTK_STATE_ACTIVE ? (DFCS_PUSHED | DFCS_FLAT)
                                 : 0));
-             release_window_dc (style, window, state_type);
+             release_window_dc (&dc_info);
            }
        }
-      else if (is_toolbar_child (widget->parent)
+      else if (is_toolbar_child (gtk_widget_get_parent (widget))
               || (!GTK_IS_BUTTON (widget) ||
                   (GTK_RELIEF_NONE == gtk_button_get_relief (GTK_BUTTON (widget)))))
        {
-         if (draw_tool_button (window, widget, style, x, y,
-                               width, height, state_type, area))
+         if (draw_tool_button (cr, widget, style, x, y,
+                               width, height, state_type))
            {
              return;
            }
        }
       else
        {
-         gboolean is_default = GTK_WIDGET_HAS_DEFAULT (widget);
+         gboolean is_default = gtk_widget_has_default (widget);
          if (xp_theme_draw
-             (window,
+             (cr,
               is_default ? XP_THEME_ELEMENT_DEFAULT_BUTTON :
               XP_THEME_ELEMENT_BUTTON, style, x, y, width, height,
-              state_type, area))
+              state_type))
            {
              return;
            }
 
-         draw_push_button (window, widget, style,
+         draw_push_button (cr, widget, style,
                            x, y, width, height, state_type, is_default);
 
          return;
@@ -1770,21 +1829,22 @@ draw_box (GtkStyle *style,
   else if (detail && (!strcmp (detail, "spinbutton_up")
                      || !strcmp (detail, "spinbutton_down")))
     {
-      if (!xp_theme_draw (window,
+      if (!xp_theme_draw (cr,
                          (!strcmp (detail, "spinbutton_up"))
                          ? XP_THEME_ELEMENT_SPIN_BUTTON_UP
                          : XP_THEME_ELEMENT_SPIN_BUTTON_DOWN,
-                         style, x, y, width, height, state_type, area))
+                         style, x, y, width, height, state_type))
        {
          RECT rect;
+         XpDCInfo dc_info;
          HDC dc;
 
-         dc = get_window_dc (style, window, state_type,
+         dc = get_window_dc (style, cr, state_type, &dc_info,
                              x, y, width, height, &rect);
          DrawEdge (dc, &rect,
                    state_type ==
                    GTK_STATE_ACTIVE ? EDGE_SUNKEN : EDGE_RAISED, BF_RECT);
-         release_window_dc (style, window, state_type);
+         release_window_dc (&dc_info);
        }
       return;
     }
@@ -1795,11 +1855,11 @@ draw_box (GtkStyle *style,
          GtkScrollbar *scrollbar = GTK_SCROLLBAR (widget);
          gboolean is_v = GTK_IS_VSCROLLBAR (widget);
 
-         if (xp_theme_draw (window,
+         if (xp_theme_draw (cr,
                             is_v
                             ? XP_THEME_ELEMENT_SCROLLBAR_V
                             : XP_THEME_ELEMENT_SCROLLBAR_H,
-                            style, x, y, width, height, state_type, area))
+                            style, x, y, width, height, state_type))
            {
              XpThemeElement gripper =
                (is_v ? XP_THEME_ELEMENT_SCROLLBAR_GRIPPER_V :
@@ -1818,15 +1878,15 @@ draw_box (GtkStyle *style,
                  return;
                }
 
-             xp_theme_draw (window, gripper, style, x, y,
-                            width, height, state_type, area);
+             xp_theme_draw (cr, gripper, style, x, y,
+                            width, height, state_type);
              return;
            }
          else
            {
-             if (scrollbar->range.adjustment->page_size >=
-                 (scrollbar->range.adjustment->upper -
-                  scrollbar->range.adjustment->lower))
+              if (gtk_adjustment_get_page_size(gtk_range_get_adjustment(&scrollbar->range)) >=
+                 (gtk_adjustment_get_page_size(gtk_range_get_adjustment(&scrollbar->range)) -
+                  gtk_adjustment_get_page_size(gtk_range_get_adjustment(&scrollbar->range))))
                {
                  return;
                }
@@ -1841,8 +1901,8 @@ draw_box (GtkStyle *style,
          XpThemeElement xp_progress_bar =
            map_gtk_progress_bar_to_xp (progress_bar, FALSE);
 
-         if (xp_theme_draw (window, xp_progress_bar, style, x, y,
-                            width, height, state_type, area))
+         if (xp_theme_draw (cr, xp_progress_bar, style, x, y,
+                            width, height, state_type))
            {
              return;
            }
@@ -1853,8 +1913,8 @@ draw_box (GtkStyle *style,
   else if (detail && strcmp (detail, "menuitem") == 0)
     {
       shadow_type = GTK_SHADOW_NONE;
-      if (draw_menu_item (window, widget, style,
-                         x, y, width, height, state_type, area))
+      if (draw_menu_item (cr, widget, style,
+                         x, y, width, height, state_type))
        {
          return;
        }
@@ -1867,8 +1927,8 @@ draw_box (GtkStyle *style,
          XpThemeElement xp_progress_bar =
            map_gtk_progress_bar_to_xp (progress_bar, TRUE);
          if (xp_theme_draw
-             (window, xp_progress_bar, style, x, y, width, height,
-              state_type, area))
+             (cr, xp_progress_bar, style, x, y, width, height,
+              state_type))
            {
              return;
            }
@@ -1881,11 +1941,11 @@ draw_box (GtkStyle *style,
        {
          gboolean is_vertical = GTK_IS_VSCROLLBAR (widget);
 
-         if (xp_theme_draw (window,
+         if (xp_theme_draw (cr,
                             is_vertical
                             ? XP_THEME_ELEMENT_TROUGH_V
                             : XP_THEME_ELEMENT_TROUGH_H,
-                            style, x, y, width, height, state_type, area))
+                            style, x, y, width, height, state_type))
            {
              return;
            }
@@ -1893,15 +1953,15 @@ draw_box (GtkStyle *style,
            {
              HDC dc;
              RECT rect;
+             XpDCInfo dc_info;
 
-             sanitize_size (window, &width, &height);
-             dc = get_window_dc (style, window, state_type, x, y, width, height, &rect);
+             dc = get_window_dc (style, cr, state_type, &dc_info, x, y, width, height, &rect);
 
              SetTextColor (dc, GetSysColor (COLOR_3DHILIGHT));
              SetBkColor (dc, GetSysColor (COLOR_BTNFACE));
              FillRect (dc, &rect, get_dither_brush ());
 
-             release_window_dc (style, window, state_type);
+             release_window_dc (&dc_info);
 
              return;
            }
@@ -1912,39 +1972,39 @@ draw_box (GtkStyle *style,
 
          if (!xp_theme_is_active ())
            {
-             parent_class->draw_box (style, window, state_type,
-                                     GTK_SHADOW_NONE, area,
+             parent_class->draw_box (style, cr, state_type,
+                                     GTK_SHADOW_NONE,
                                      widget, detail, x, y, width, height);
            }
 
          if (is_vertical)
            {
              if (xp_theme_draw
-                 (window, XP_THEME_ELEMENT_SCALE_TROUGH_V,
+                 (cr, XP_THEME_ELEMENT_SCALE_TROUGH_V,
                   style, (2 * x + width) / 2, y, 2, height,
-                  state_type, area))
+                  state_type))
                {
                  return;
                }
 
-             parent_class->draw_box (style, window, state_type,
+             parent_class->draw_box (style, cr, state_type,
                                      GTK_SHADOW_ETCHED_IN,
-                                     area, NULL, NULL,
+                                     NULL, NULL,
                                      (2 * x + width) / 2, y, 1, height);
            }
          else
            {
              if (xp_theme_draw
-                 (window, XP_THEME_ELEMENT_SCALE_TROUGH_H,
+                 (cr, XP_THEME_ELEMENT_SCALE_TROUGH_H,
                   style, x, (2 * y + height) / 2, width, 2,
-                  state_type, area))
+                  state_type))
                {
                  return;
                }
 
-             parent_class->draw_box (style, window, state_type,
+             parent_class->draw_box (style, cr, state_type,
                                      GTK_SHADOW_ETCHED_IN,
-                                     area, NULL, NULL, x,
+                                     NULL, NULL, x,
                                      (2 * y + height) / 2, width, 1);
            }
 
@@ -1953,8 +2013,8 @@ draw_box (GtkStyle *style,
     }
   else if (detail && strcmp (detail, "optionmenu") == 0)
     {
-      if (xp_theme_draw (window, XP_THEME_ELEMENT_EDIT_TEXT,
-                        style, x, y, width, height, state_type, area))
+      if (xp_theme_draw (cr, XP_THEME_ELEMENT_EDIT_TEXT,
+                        style, x, y, width, height, state_type))
        {
          return;
        }
@@ -1970,9 +2030,8 @@ draw_box (GtkStyle *style,
               || strcmp (detail, "toolbar") == 0
               || strcmp (detail, "menubar") == 0))
     {
-      sanitize_size (window, &width, &height);
-      if (xp_theme_draw (window, XP_THEME_ELEMENT_REBAR,
-                        style, x, y, width, height, state_type, area))
+      if (xp_theme_draw (cr, XP_THEME_ELEMENT_REBAR,
+                        style, x, y, width, height, state_type))
        {
          return;
        }
@@ -1986,10 +2045,8 @@ draw_box (GtkStyle *style,
     }
   else if (detail && !strcmp (detail, "notebook") && GTK_IS_NOTEBOOK (widget))
     {
-      GtkNotebook *notebook = GTK_NOTEBOOK (widget);
-
-      if (xp_theme_draw (window, XP_THEME_ELEMENT_TAB_PANE, style,
-                        x, y, width, height, state_type, area))
+      if (xp_theme_draw (cr, XP_THEME_ELEMENT_TAB_PANE, style,
+                        x, y, width, height, state_type))
        {
          return;
        }
@@ -2002,8 +2059,8 @@ draw_box (GtkStyle *style,
       if (name && !strcmp (name, "gtk-tooltips"))
        {
          if (xp_theme_draw
-             (window, XP_THEME_ELEMENT_TOOLTIP, style, x, y, width,
-              height, state_type, area))
+             (cr, XP_THEME_ELEMENT_TOOLTIP, style, x, y, width,
+              height, state_type))
            {
              return;
            }
@@ -2011,9 +2068,10 @@ draw_box (GtkStyle *style,
            {
              HBRUSH brush;
              RECT rect;
+             XpDCInfo dc_info;
              HDC hdc;
 
-             hdc = get_window_dc (style, window, state_type, x, y, width, height, &rect);
+             hdc = get_window_dc (style, cr, state_type, &dc_info, x, y, width, height, &rect);
 
              brush = GetSysColorBrush (COLOR_3DDKSHADOW);
 
@@ -2025,14 +2083,14 @@ draw_box (GtkStyle *style,
              InflateRect (&rect, -1, -1);
              FillRect (hdc, &rect, (HBRUSH) (COLOR_INFOBK + 1));
 
-             release_window_dc (style, window, state_type);
+             release_window_dc (&dc_info);
 
              return;
            }
        }
     }
 
-  parent_class->draw_box (style, window, state_type, shadow_type, area,
+  parent_class->draw_box (style, cr, state_type, shadow_type,
                          widget, detail, x, y, width, height);
 
   if (detail && strcmp (detail, "optionmenu") == 0)
@@ -2043,8 +2101,6 @@ draw_box (GtkStyle *style,
 
       option_menu_get_props (widget, &indicator_size, &indicator_spacing);
 
-      sanitize_size (window, &width, &height);
-
       if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL)
        {
          vline_x =
@@ -2057,7 +2113,7 @@ draw_box (GtkStyle *style,
                                 indicator_spacing.left +
                                 indicator_spacing.right) - style->xthickness;
 
-         parent_class->draw_vline (style, window, state_type, area, widget,
+         parent_class->draw_vline (style, cr, state_type, widget,
                                    detail,
                                    y + style->ythickness + 1,
                                    y + height - style->ythickness - 3, vline_x);
@@ -2067,10 +2123,9 @@ draw_box (GtkStyle *style,
 
 static void
 draw_tab (GtkStyle *style,
-         GdkWindow *window,
+         cairo_t *cr,
          GtkStateType state,
          GtkShadowType shadow,
-         GdkRectangle *area,
          GtkWidget *widget,
          const gchar *detail, gint x, gint y, gint width, gint height)
 {
@@ -2080,14 +2135,17 @@ draw_tab (GtkStyle *style,
   gint arrow_height;
 
   g_return_if_fail (style != NULL);
-  g_return_if_fail (window != NULL);
+  g_return_if_fail (cr != NULL);
 
   if (detail && !strcmp (detail, "optionmenutab"))
     {
-      if (xp_theme_draw (window, XP_THEME_ELEMENT_COMBOBUTTON,
-                        style, x - 5, widget->allocation.y + 1,
-                        width + 10, widget->allocation.height - 2,
-                        state, area))
+      GtkAllocation allocation;
+
+      gtk_widget_get_allocation (widget, &allocation);
+      if (xp_theme_draw (cr, XP_THEME_ELEMENT_COMBOBUTTON,
+                        style, x - 5, allocation.y + 1,
+                        width + 10, allocation.height - 2,
+                        state))
        {
          return;
        }
@@ -2100,7 +2158,7 @@ draw_tab (GtkStyle *style,
 
   y += (height - arrow_height) / 2;
 
-  draw_varrow (window, style->black_gc, shadow, area, GTK_ARROW_DOWN,
+  draw_varrow (cr, &style->black, shadow, GTK_ARROW_DOWN,
               x, y, indicator_size.width, arrow_height);
 }
 
@@ -2218,18 +2276,23 @@ DrawTab (HDC hdc, const RECT R, gint32 aPosition, gboolean aSelected,
 
 static gboolean
 draw_themed_tab_button (GtkStyle *style,
-                       GdkWindow *window,
+                       cairo_t *cr,
                        GtkStateType state_type,
                        GtkNotebook *notebook,
                        gint x, gint y,
                        gint width, gint height, gint gap_side)
 {
+/* FIXME: poop
   GdkPixmap *pixmap = NULL;
+ */
   gint border_width =
     gtk_container_get_border_width (GTK_CONTAINER (notebook));
   GtkWidget *widget = GTK_WIDGET (notebook);
-  GdkRectangle draw_rect, clip_rect;
+  GdkRectangle draw_rect;
   GdkPixbufRotation rotation = GDK_PIXBUF_ROTATE_NONE;
+  GtkAllocation allocation;
+
+  gtk_widget_get_allocation (widget, &allocation);
 
   if (gap_side == GTK_POS_TOP)
     {
@@ -2242,8 +2305,9 @@ draw_themed_tab_button (GtkStyle *style,
          draw_rect.width = width + 2;
          draw_rect.height = height;
 
-         clip_rect = draw_rect;
+/* FIXME: wtf?
          clip_rect.height--;
+ */
        }
       else
        {
@@ -2251,15 +2315,14 @@ draw_themed_tab_button (GtkStyle *style,
          draw_rect.y = y;
          draw_rect.width = width - 2;
          draw_rect.height = height - 2;
-         clip_rect = draw_rect;
        }
 
       /* If we are currently drawing the right-most tab, and if that tab is the selected tab... */
-      widget_right = widget->allocation.x + widget->allocation.width - border_width - 2;
+      widget_right = allocation.x + allocation.width - border_width - 2;
 
       if (draw_rect.x + draw_rect.width >= widget_right)
        {
-         draw_rect.width = clip_rect.width = widget_right - draw_rect.x;
+         draw_rect.width = widget_right - draw_rect.x;
        }
     }
   if (gap_side == GTK_POS_BOTTOM)
@@ -2272,8 +2335,6 @@ draw_themed_tab_button (GtkStyle *style,
          draw_rect.y = y;
          draw_rect.width = width + 2;
          draw_rect.height = height;
-
-         clip_rect = draw_rect;
        }
       else
        {
@@ -2281,15 +2342,14 @@ draw_themed_tab_button (GtkStyle *style,
          draw_rect.y = y + 2;
          draw_rect.width = width - 2;
          draw_rect.height = height - 2;
-         clip_rect = draw_rect;
        }
 
       /* If we are currently drawing the right-most tab, and if that tab is the selected tab... */
-      widget_right = widget->allocation.x + widget->allocation.width - border_width - 2;
+      widget_right = allocation.x + allocation.width - border_width - 2;
 
       if (draw_rect.x + draw_rect.width >= widget_right)
        {
-         draw_rect.width = clip_rect.width = widget_right - draw_rect.x;
+         draw_rect.width = widget_right - draw_rect.x;
        }
 
       rotation = GDK_PIXBUF_ROTATE_UPSIDEDOWN;
@@ -2305,8 +2365,9 @@ draw_themed_tab_button (GtkStyle *style,
          draw_rect.width = width;
          draw_rect.height = height + 2;
 
-         clip_rect = draw_rect;
+/* FIXME: wtf?
          clip_rect.width--;
+ */
        }
       else
        {
@@ -2314,15 +2375,14 @@ draw_themed_tab_button (GtkStyle *style,
          draw_rect.y = y + 2;
          draw_rect.width = width - 2;
          draw_rect.height = height - 2;
-         clip_rect = draw_rect;
        }
 
       /* If we are currently drawing the bottom-most tab, and if that tab is the selected tab... */
-      widget_bottom = widget->allocation.x + widget->allocation.height - border_width - 2;
+      widget_bottom = allocation.x + allocation.height - border_width - 2;
 
       if (draw_rect.y + draw_rect.height >= widget_bottom)
        {
-         draw_rect.height = clip_rect.height = widget_bottom - draw_rect.y;
+         draw_rect.height = widget_bottom - draw_rect.y;
        }
 
       rotation = GDK_PIXBUF_ROTATE_COUNTERCLOCKWISE;
@@ -2338,8 +2398,9 @@ draw_themed_tab_button (GtkStyle *style,
          draw_rect.width = width;
          draw_rect.height = height + 2;
 
-         clip_rect = draw_rect;
+/* FIXME: wtf?
          clip_rect.width--;
+ */
        }
       else
        {
@@ -2347,15 +2408,14 @@ draw_themed_tab_button (GtkStyle *style,
          draw_rect.y = y + 2;
          draw_rect.width = width - 2;
          draw_rect.height = height - 2;
-         clip_rect = draw_rect;
        }
 
       /* If we are currently drawing the bottom-most tab, and if that tab is the selected tab... */
-      widget_bottom = widget->allocation.x + widget->allocation.height - border_width - 2;
+      widget_bottom = allocation.x + allocation.height - border_width - 2;
 
       if (draw_rect.y + draw_rect.height >= widget_bottom)
        {
-         draw_rect.height = clip_rect.height = widget_bottom - draw_rect.y;
+         draw_rect.height = widget_bottom - draw_rect.y;
        }
 
       rotation = GDK_PIXBUF_ROTATE_CLOCKWISE;
@@ -2363,25 +2423,28 @@ draw_themed_tab_button (GtkStyle *style,
 
   if (gap_side == GTK_POS_TOP)
     {
-      if (!xp_theme_draw (window, XP_THEME_ELEMENT_TAB_ITEM, style,
+      if (!xp_theme_draw (cr, XP_THEME_ELEMENT_TAB_ITEM, style,
                          draw_rect.x, draw_rect.y,
                          draw_rect.width, draw_rect.height,
-                         state_type, &clip_rect))
+                         state_type))
        {
          return FALSE;
        }
     }
   else
     {
+/* FIXME: poop */
+#if 0
       GdkPixbuf *pixbuf;
       GdkPixbuf *rotated;
 
       if (gap_side == GTK_POS_LEFT || gap_side == GTK_POS_RIGHT)
        {
-         pixmap = gdk_pixmap_new (window, clip_rect.height, clip_rect.width, -1);
+         pixmap = gdk_pixmap_new (cr, draw_rect.height, draw_rect.width, -1);
 
          if (!xp_theme_draw (pixmap, XP_THEME_ELEMENT_TAB_ITEM, style,
-                             draw_rect.y - clip_rect.y, draw_rect.x - clip_rect.x,
+/* FIXME: wtf? */
+                             draw_rect.y - draw_rect.y, draw_rect.x - draw_rect.x,
                              draw_rect.height, draw_rect.width, state_type, 0))
            {
              g_object_unref (pixmap);
@@ -2389,15 +2452,16 @@ draw_themed_tab_button (GtkStyle *style,
            }
 
          pixbuf = gdk_pixbuf_get_from_drawable (NULL, pixmap, NULL, 0, 0, 0, 0,
-                                                clip_rect.height, clip_rect.width);
+                                                draw_rect.height, draw_rect.width);
          g_object_unref (pixmap);
        }
       else
        {
-         pixmap = gdk_pixmap_new (window, clip_rect.width, clip_rect.height, -1);
+         pixmap = gdk_pixmap_new (cr, draw_rect.width, draw_rect.height, -1);
 
          if (!xp_theme_draw (pixmap, XP_THEME_ELEMENT_TAB_ITEM, style,
-                             draw_rect.x - clip_rect.x, draw_rect.y - clip_rect.y,
+/* FIXME: wtf? */
+                             draw_rect.x - draw_rect.x, draw_rect.y - draw_rect.y,
                              draw_rect.width, draw_rect.height, state_type, 0))
            {
              g_object_unref (pixmap);
@@ -2405,7 +2469,7 @@ draw_themed_tab_button (GtkStyle *style,
            }
 
          pixbuf = gdk_pixbuf_get_from_drawable (NULL, pixmap, NULL, 0, 0, 0, 0,
-                                                clip_rect.width, clip_rect.height);
+                                                draw_rect.width, draw_rect.height);
          g_object_unref (pixmap);
        }
 
@@ -2418,7 +2482,7 @@ draw_themed_tab_button (GtkStyle *style,
       //       pixel at the top.  There may be a better solution than this if someone
       //       has time to discover it.
       if (gap_side == GTK_POS_BOTTOM && state_type == GTK_STATE_NORMAL
-         && x == widget->allocation.x)
+         && x == allocation.x)
        {
          int rowstride = gdk_pixbuf_get_rowstride (pixbuf);
          int n_channels = gdk_pixbuf_get_n_channels (pixbuf);
@@ -2433,10 +2497,10 @@ draw_themed_tab_button (GtkStyle *style,
            }
        }
 
-      gdk_draw_pixbuf (window, NULL, pixbuf, 0, 0, clip_rect.x, clip_rect.y,
-                      clip_rect.width, clip_rect.height, GDK_RGB_DITHER_NONE,
-                      0, 0);
+      gdk_cairo_set_source_pixbuf (cr, pixbuf, clip_rect.x, clip_rect.y);
+      cairo_paint (cr);
       g_object_unref (pixbuf);
+#endif
     }
 
   return TRUE;
@@ -2444,10 +2508,9 @@ draw_themed_tab_button (GtkStyle *style,
 
 static gboolean
 draw_tab_button (GtkStyle *style,
-                GdkWindow *window,
+                cairo_t *cr,
                 GtkStateType state_type,
                 GtkShadowType shadow_type,
-                GdkRectangle *area,
                 GtkWidget *widget,
                 const gchar *detail,
                 gint x, gint y, gint width, gint height, gint gap_side)
@@ -2456,10 +2519,11 @@ draw_tab_button (GtkStyle *style,
     {
       /* experimental tab-drawing code from mozilla */
       RECT rect;
+      XpDCInfo dc_info;
       HDC dc;
       gint32 aPosition;
 
-      dc = get_window_dc (style, window, state_type, x, y, width, height, &rect);
+      dc = get_window_dc (style, cr, state_type, &dc_info, x, y, width, height, &rect);
 
       if (gap_side == GTK_POS_TOP)
        aPosition = BF_TOP;
@@ -2472,17 +2536,17 @@ draw_tab_button (GtkStyle *style,
 
       if (state_type == GTK_STATE_PRELIGHT)
        state_type = GTK_STATE_NORMAL;
-      if (area)
-       gdk_gc_set_clip_rectangle (style->dark_gc[state_type], area);
+
+/* FIXME: wtf? 
+           gdk_cairo_set_source_color (cr, &style->dark[state_type]);
+ */
 
       DrawTab (dc, rect, aPosition,
               state_type != GTK_STATE_PRELIGHT,
               (gap_side != GTK_POS_LEFT), (gap_side != GTK_POS_RIGHT));
 
-      if (area)
-       gdk_gc_set_clip_rectangle (style->dark_gc[state_type], NULL);
+      release_window_dc (&dc_info);
 
-      release_window_dc (style, window, state_type);
       return TRUE;
     }
 
@@ -2491,10 +2555,9 @@ draw_tab_button (GtkStyle *style,
 
 static void
 draw_extension (GtkStyle *style,
-               GdkWindow *window,
+               cairo_t *cr,
                GtkStateType state_type,
                GtkShadowType shadow_type,
-               GdkRectangle *area,
                GtkWidget *widget,
                const gchar *detail,
                gint x, gint y,
@@ -2504,29 +2567,33 @@ draw_extension (GtkStyle *style,
     {
       GtkNotebook *notebook = GTK_NOTEBOOK (widget);
 
-      /* Why this differs from gap_side, I have no idea.. */
-      int real_gap_side = gtk_notebook_get_tab_pos (notebook);
+      /* draw_themed_tab_button and draw_tab_button expect to work with tab
+       * position, instead of simply taking the "side of the gap" (gap_side)
+       * which simply said is the side of the tab that touches the notebook
+       * frame and is always the exact opposite of the gap side... */
+      int tab_pos = gtk_notebook_get_tab_pos (notebook);
 
-      if (!draw_themed_tab_button (style, window, state_type,
-                                  GTK_NOTEBOOK (widget), x, y,
-                                  width, height, real_gap_side))
+      if (!draw_themed_tab_button (style, cr, state_type,
+                                  notebook, x, y,
+                                  width, height, tab_pos))
        {
-         if (!draw_tab_button (style, window, state_type,
-                               shadow_type, area, widget,
-                               detail, x, y, width, height, real_gap_side))
+         if (!draw_tab_button (style, cr, state_type,
+                               shadow_type, widget,
+                               detail, x, y, width, height, tab_pos))
            {
-             parent_class->draw_extension (style, window, state_type,
-                                           shadow_type, area, widget, detail,
+             /* GtkStyle expects the usual gap_side */
+             parent_class->draw_extension (style, cr, state_type,
+                                           shadow_type, widget, detail,
                                            x, y, width, height,
-                                           real_gap_side);
+                                           gap_side);
            }
        }
     }
 }
 
 static void
-draw_box_gap (GtkStyle *style, GdkWindow *window, GtkStateType state_type,
-             GtkShadowType shadow_type, GdkRectangle *area,
+draw_box_gap (GtkStyle *style, cairo_t *cr, GtkStateType state_type,
+             GtkShadowType shadow_type,
              GtkWidget *widget, const gchar *detail, gint x,
              gint y, gint width, gint height, GtkPositionType gap_side,
              gint gap_x, gint gap_width)
@@ -2540,41 +2607,41 @@ draw_box_gap (GtkStyle *style, GdkWindow *window, GtkStateType state_type,
       if (side == GTK_POS_TOP)
        {
          x2 = x;
-         y2 = y - notebook->tab_vborder;
+         y2 = y - gtk_notebook_get_tab_vborder (notebook);
          w2 = width;
-         h2 = height + notebook->tab_vborder * 2;
+         h2 = height + gtk_notebook_get_tab_vborder (notebook) * 2;
        }
       else if (side == GTK_POS_BOTTOM)
        {
          x2 = x;
          y2 = y;
          w2 = width;
-         h2 = height + notebook->tab_vborder * 2;
+         h2 = height + gtk_notebook_get_tab_vborder (notebook) * 2;
        }
       else if (side == GTK_POS_LEFT)
        {
-         x2 = x - notebook->tab_hborder;
+         x2 = x - gtk_notebook_get_tab_hborder (notebook);
          y2 = y;
-         w2 = width + notebook->tab_hborder;
+         w2 = width + gtk_notebook_get_tab_hborder (notebook);
          h2 = height;
        }
       else if (side == GTK_POS_RIGHT)
        {
          x2 = x;
          y2 = y;
-         w2 = width + notebook->tab_hborder * 2;
+         w2 = width + gtk_notebook_get_tab_hborder (notebook) * 2;
          h2 = height;
        }
 
-      if (xp_theme_draw (window, XP_THEME_ELEMENT_TAB_PANE, style,
-                        x2, y2, w2, h2, state_type, area))
+      if (xp_theme_draw (cr, XP_THEME_ELEMENT_TAB_PANE, style,
+                        x2, y2, w2, h2, state_type))
        {
          return;
        }
     }
 
-  parent_class->draw_box_gap (style, window, state_type, shadow_type,
-                             area, widget, detail, x, y, width, height,
+  parent_class->draw_box_gap (style, cr, state_type, shadow_type,
+                             widget, detail, x, y, width, height,
                              gap_side, gap_x, gap_width);
 }
 
@@ -2600,14 +2667,23 @@ is_popup_window_child (GtkWidget *widget)
 }
 
 static void
-draw_flat_box (GtkStyle *style, GdkWindow *window,
+draw_flat_box (GtkStyle *style, cairo_t *cr,
               GtkStateType state_type, GtkShadowType shadow_type,
-              GdkRectangle *area, GtkWidget *widget,
+              GtkWidget *widget,
               const gchar *detail, gint x, gint y, gint width, gint height)
 {
   if (detail)
     {
-      if (!strcmp (detail, "checkbutton"))
+      if (state_type == GTK_STATE_SELECTED &&
+         (!strncmp ("cell_even", detail, 9) || !strncmp ("cell_odd", detail, 8)))
+       {
+          GdkColor *gc = gtk_widget_has_focus (widget) ? &style->base[state_type] : &style->base[GTK_STATE_ACTIVE];
+
+          _cairo_draw_rectangle (cr, gc, TRUE, x, y, width, height);
+
+         return;
+       }
+      else if (!strcmp (detail, "checkbutton"))
        {
          if (state_type == GTK_STATE_PRELIGHT)
            {
@@ -2616,18 +2692,19 @@ draw_flat_box (GtkStyle *style, GdkWindow *window,
        }
     }
 
-  parent_class->draw_flat_box (style, window, state_type, shadow_type,
-                              area, widget, detail, x, y, width, height);
+  parent_class->draw_flat_box (style, cr, state_type, shadow_type,
+                              widget, detail, x, y, width, height);
 }
 
 static gboolean
-draw_menu_border (GdkWindow *win, GtkStyle *style,
+draw_menu_border (cairo_t *cr, GtkStyle *style,
                  gint x, gint y, gint width, gint height)
 {
   RECT rect;
+  XpDCInfo dc_info;
   HDC dc;
 
-  dc = get_window_dc (style, win, GTK_STATE_NORMAL, x, y, width, height, &rect);
+  dc = get_window_dc (style, cr, GTK_STATE_NORMAL, &dc_info, x, y, width, height, &rect);
 
   if (!dc)
     return FALSE;
@@ -2641,17 +2718,16 @@ draw_menu_border (GdkWindow *win, GtkStyle *style,
       DrawEdge (dc, &rect, EDGE_RAISED, BF_RECT);
     }
 
-  release_window_dc (style, win, GTK_STATE_NORMAL);
+  release_window_dc (&dc_info);
 
   return TRUE;
 }
 
 static void
 draw_shadow (GtkStyle *style,
-            GdkWindow *window,
+            cairo_t *cr,
             GtkStateType state_type,
             GtkShadowType shadow_type,
-            GdkRectangle *area,
             GtkWidget *widget,
             const gchar *detail, gint x, gint y, gint width, gint height)
 {
@@ -2660,13 +2736,14 @@ draw_shadow (GtkStyle *style,
 
   if (detail && !strcmp (detail, "frame"))
     {
+
       HDC dc;
       RECT rect;
+      XpDCInfo dc_info;
 
 
 
-      dc = get_window_dc (style, window, state_type, x, y, width, height, &rect);
+      dc = get_window_dc (style, cr, state_type, &dc_info, x, y, width, height, &rect);
       if (is_combo_box_child (widget))
         {
           FillRect (dc, &rect, GetSysColorBrush (COLOR_WINDOW));
@@ -2704,7 +2781,7 @@ draw_shadow (GtkStyle *style,
            }
        }
 
-      release_window_dc (style, window, state_type);
+      release_window_dc (&dc_info);
 
       return;
     }
@@ -2713,25 +2790,26 @@ draw_shadow (GtkStyle *style,
       if (shadow_type != GTK_SHADOW_IN)
        return;
 
-      if (!xp_theme_draw (window, XP_THEME_ELEMENT_EDIT_TEXT, style,
-                         x, y, width, height, state_type, area))
+      if (!xp_theme_draw (cr, XP_THEME_ELEMENT_EDIT_TEXT, style,
+                         x, y, width, height, state_type))
        {
          HDC dc;
          RECT rect;
+         XpDCInfo dc_info;
 
-         dc = get_window_dc (style, window, state_type,
+         dc = get_window_dc (style, cr, state_type, &dc_info,
                              x, y, width, height, &rect);
 
          DrawEdge (dc, &rect, EDGE_SUNKEN, BF_RECT);
-         release_window_dc (style, window, state_type);
+         release_window_dc (&dc_info);
        }
 
       return;
     }
 
   if (detail && !strcmp (detail, "scrolled_window") &&
-      xp_theme_draw (window, XP_THEME_ELEMENT_EDIT_TEXT, style,
-                    x, y, width, height, state_type, area))
+      xp_theme_draw (cr, XP_THEME_ELEMENT_EDIT_TEXT, style,
+                    x, y, width, height, state_type))
     {
       return;
     }
@@ -2741,7 +2819,7 @@ draw_shadow (GtkStyle *style,
 
   if (detail && !strcmp (detail, "menu"))
     {
-      if (draw_menu_border (window, style, x, y, width, height))
+      if (draw_menu_border (cr, style, x, y, width, height))
        {
          return;
        }
@@ -2766,16 +2844,15 @@ draw_shadow (GtkStyle *style,
        {
          HDC dc;
          RECT rect;
+         XpDCInfo dc_info;
          HGDIOBJ old_pen = NULL;
          GtkPositionType pos;
 
-         sanitize_size (window, &width, &height);
-
          if (is_handlebox)
            {
              pos = gtk_handle_box_get_handle_position (GTK_HANDLE_BOX (widget));
              /*
-                If the handle box is at left side, 
+                If the handle box is at left side,
                 we shouldn't draw its right border.
                 The same holds true for top, right, and bottom.
               */
@@ -2818,7 +2895,7 @@ draw_shadow (GtkStyle *style,
                }
            }
 
-         dc = get_window_dc (style, window, state_type, x, y, width, height, &rect);
+         dc = get_window_dc (style, cr, state_type, &dc_info, x, y, width, height, &rect);
 
          if (pos != GTK_POS_LEFT)
            {
@@ -2846,7 +2923,7 @@ draw_shadow (GtkStyle *style,
            }
          if (old_pen)
            SelectObject (dc, old_pen);
-         release_window_dc (style, window, state_type);
+         release_window_dc (&dc_info);
        }
 
       return;
@@ -2857,64 +2934,56 @@ draw_shadow (GtkStyle *style,
       return;
     }
 
-  parent_class->draw_shadow (style, window, state_type, shadow_type, area,
+  parent_class->draw_shadow (style, cr, state_type, shadow_type,
                             widget, detail, x, y, width, height);
 }
 
 static void
 draw_hline (GtkStyle *style,
-           GdkWindow *window,
+           cairo_t *cr,
            GtkStateType state_type,
-           GdkRectangle *area,
            GtkWidget *widget,
            const gchar *detail, gint x1, gint x2, gint y)
 {
   if (xp_theme_is_active () && detail && !strcmp (detail, "menuitem"))
     {
+      gint cx, cy;
+      gint new_y, new_height;
+      gint y_offset;
+
+      xp_theme_get_element_dimensions (XP_THEME_ELEMENT_MENU_SEPARATOR,
+                                      state_type,
+                                      &cx, &cy);
+
+      /* Center the separator */
+      y_offset = (cy / 2) - 1;
+      new_y = (y - y_offset) >= 0 ? y - y_offset : y;
+      new_height = cy;
+
       if (xp_theme_draw
-         (window, XP_THEME_ELEMENT_MENU_SEPARATOR, style, x1, y, x2, 1,
-          state_type, area))
+         (cr, XP_THEME_ELEMENT_MENU_SEPARATOR, style, x1, new_y, x2, new_height,
+          state_type))
        {
          return;
        }
       else
        {
-         if (area)
-           {
-             gdk_gc_set_clip_rectangle (style->dark_gc[state_type], area);
-           }
-
-         gdk_draw_line (window, style->dark_gc[state_type], x1, y, x2, y);
+          _cairo_draw_line (cr, &style->dark[state_type], x1, y, x2, y);
 
-         if (area)
-           {
-             gdk_gc_set_clip_rectangle (style->dark_gc[state_type], NULL);
-           }
        }
     }
   else
     {
       if (style->ythickness == 2)
        {
-         if (area)
-           {
-             gdk_gc_set_clip_rectangle (style->dark_gc[state_type], area);
-             gdk_gc_set_clip_rectangle (style->light_gc[state_type], area);
-           }
-
-         gdk_draw_line (window, style->dark_gc[state_type], x1, y, x2, y);
+          _cairo_draw_line (cr, &style->dark[state_type], x1, y, x2, y);
          ++y;
-         gdk_draw_line (window, style->light_gc[state_type], x1, y, x2, y);
+          _cairo_draw_line (cr, &style->light[state_type], x1, y, x2, y);
 
-         if (area)
-           {
-             gdk_gc_set_clip_rectangle (style->dark_gc[state_type], NULL);
-             gdk_gc_set_clip_rectangle (style->light_gc[state_type], NULL);
-           }
        }
       else
        {
-         parent_class->draw_hline (style, window, state_type, area, widget,
+         parent_class->draw_hline (style, cr, state_type, widget,
                                    detail, x1, x2, y);
        }
     }
@@ -2922,67 +2991,53 @@ draw_hline (GtkStyle *style,
 
 static void
 draw_vline (GtkStyle *style,
-           GdkWindow *window,
+           cairo_t *cr,
            GtkStateType state_type,
-           GdkRectangle *area,
            GtkWidget *widget,
            const gchar *detail, gint y1, gint y2, gint x)
 {
   if (style->xthickness == 2)
     {
-      if (area)
-       {
-         gdk_gc_set_clip_rectangle (style->dark_gc[state_type], area);
-         gdk_gc_set_clip_rectangle (style->light_gc[state_type], area);
-       }
-
-      gdk_draw_line (window, style->dark_gc[state_type], x, y1, x, y2);
+      _cairo_draw_line (cr, &style->dark[state_type], x, y1, x, y2);
       ++x;
-      gdk_draw_line (window, style->light_gc[state_type], x, y1, x, y2);
+      _cairo_draw_line (cr, &style->light[state_type], x, y1, x, y2);
 
-      if (area)
-       {
-         gdk_gc_set_clip_rectangle (style->dark_gc[state_type], NULL);
-         gdk_gc_set_clip_rectangle (style->light_gc[state_type], NULL);
-       }
     }
   else
     {
-      parent_class->draw_vline (style, window, state_type, area, widget,
+      parent_class->draw_vline (style, cr, state_type, widget,
                                detail, y1, y2, x);
     }
 }
 
 static void
 draw_slider (GtkStyle *style,
-            GdkWindow *window,
+            cairo_t *cr,
             GtkStateType state_type,
             GtkShadowType shadow_type,
-            GdkRectangle *area,
             GtkWidget *widget,
             const gchar *detail,
             gint x,
             gint y, gint width, gint height, GtkOrientation orientation)
 {
   if (GTK_IS_SCALE (widget) &&
-      xp_theme_draw (window, ((orientation == GTK_ORIENTATION_VERTICAL) ?
+      xp_theme_draw (cr, ((orientation == GTK_ORIENTATION_VERTICAL) ?
                              XP_THEME_ELEMENT_SCALE_SLIDER_V :
                              XP_THEME_ELEMENT_SCALE_SLIDER_H), style, x, y, width,
-                    height, state_type, area))
+                    height, state_type))
     {
       return;
     }
 
-  parent_class->draw_slider (style, window, state_type, shadow_type, area,
+  parent_class->draw_slider (style, cr, state_type, shadow_type,
                             widget, detail, x, y, width, height,
                             orientation);
 }
 
 static void
 draw_resize_grip (GtkStyle *style,
-                 GdkWindow *window,
+                 cairo_t *cr,
                  GtkStateType state_type,
-                 GdkRectangle *area,
                  GtkWidget *widget,
                  const gchar *detail,
                  GdkWindowEdge edge, gint x, gint y, gint width, gint height)
@@ -2990,39 +3045,37 @@ draw_resize_grip (GtkStyle *style,
   if (detail && !strcmp (detail, "statusbar"))
     {
       if (xp_theme_draw
-         (window, XP_THEME_ELEMENT_STATUS_GRIPPER, style, x, y, width,
-          height, state_type, area))
+         (cr, XP_THEME_ELEMENT_STATUS_GRIPPER, style, x, y, width,
+          height, state_type))
        {
          return;
        }
       else
        {
          RECT rect;
-         HDC dc = get_window_dc (style, window, state_type, x, y, width, height, &rect);
+         XpDCInfo dc_info;
+         HDC dc = get_window_dc (style, cr, state_type, &dc_info, x, y, width, height, &rect);
 
-         if (area)
-           gdk_gc_set_clip_rectangle (style->dark_gc[state_type], area);
+/* FIXME: wtf?
+              gdk_cairo_set_source_color (cr, &style->dark[state_type]);
+ */
 
          DrawFrameControl (dc, &rect, DFC_SCROLL, DFCS_SCROLLSIZEGRIP);
-         release_window_dc (style, window, state_type);
-
-         if (area)
-           gdk_gc_set_clip_rectangle (style->dark_gc[state_type], NULL);
+         release_window_dc (&dc_info);
 
          return;
        }
     }
 
-  parent_class->draw_resize_grip (style, window, state_type, area,
+  parent_class->draw_resize_grip (style, cr, state_type,
                                  widget, detail, edge, x, y, width, height);
 }
 
 static void
 draw_handle (GtkStyle *style,
-            GdkWindow *window,
+            cairo_t *cr,
             GtkStateType state_type,
             GtkShadowType shadow_type,
-            GdkRectangle *area,
             GtkWidget *widget,
             const gchar *detail,
             gint x,
@@ -3030,13 +3083,12 @@ draw_handle (GtkStyle *style,
 {
   HDC dc;
   RECT rect;
+  XpDCInfo dc_info;
 
   if (is_toolbar_child (widget))
     {
       XpThemeElement hndl;
 
-      sanitize_size (window, &width, &height);
-
       if (GTK_IS_HANDLE_BOX (widget))
        {
          GtkPositionType pos;
@@ -3057,13 +3109,13 @@ draw_handle (GtkStyle *style,
       else
        hndl = XP_THEME_ELEMENT_REBAR_GRIPPER_H;
 
-      if (xp_theme_draw (window, hndl, style, x, y, width, height,
-                        state_type, area))
+      if (xp_theme_draw (cr, hndl, style, x, y, width, height,
+                        state_type))
        {
          return;
        }
 
-      dc = get_window_dc (style, window, state_type, x, y, width, height, &rect);
+      dc = get_window_dc (style, cr, state_type, &dc_info, x, y, width, height, &rect);
 
       if (orientation == GTK_ORIENTATION_VERTICAL)
        {
@@ -3081,24 +3133,22 @@ draw_handle (GtkStyle *style,
        }
 
       draw_3d_border (dc, &rect, FALSE);
-      release_window_dc (style, window, state_type);
+      release_window_dc (&dc_info);
       return;
     }
 
   if (!GTK_IS_PANED (widget))
     {
       gint xthick, ythick;
-      GdkGC *light_gc, *dark_gc, *shadow_gc;
+      GdkColor *light, *dark, *shadow;
       GdkRectangle dest;
 
-      sanitize_size (window, &width, &height);
-
-      gtk_paint_box (style, window, state_type, shadow_type, area,
+      gtk_paint_box (style, cr, state_type, shadow_type,
                     widget, detail, x, y, width, height);
 
-      light_gc = style->light_gc[state_type];
-      dark_gc = style->dark_gc[state_type];
-      shadow_gc = style->mid_gc[state_type];
+      light = &style->light[state_type];
+      dark = &style->dark[state_type];
+      shadow = &style->mid[state_type];
 
       xthick = style->xthickness;
       ythick = style->ythickness;
@@ -3113,49 +3163,41 @@ draw_handle (GtkStyle *style,
       else
        dest.y += 2;
 
-      gdk_gc_set_clip_rectangle (light_gc, &dest);
-      gdk_gc_set_clip_rectangle (dark_gc, &dest);
-      gdk_gc_set_clip_rectangle (shadow_gc, &dest);
-
       if (dest.width < dest.height)
        {
-         gdk_draw_line (window, light_gc, dest.x, dest.y, dest.x,
+          _cairo_draw_line (cr, light, dest.x, dest.y, dest.x,
                         dest.height);
-         gdk_draw_line (window, dark_gc, dest.x + (dest.width / 2),
+          _cairo_draw_line (cr, dark, dest.x + (dest.width / 2),
                         dest.y, dest.x + (dest.width / 2), dest.height);
-         gdk_draw_line (window, shadow_gc, dest.x + dest.width,
+          _cairo_draw_line (cr, shadow, dest.x + dest.width,
                         dest.y, dest.x + dest.width, dest.height);
        }
       else
        {
-         gdk_draw_line (window, light_gc, dest.x, dest.y,
+          _cairo_draw_line (cr, light, dest.x, dest.y,
                         dest.x + dest.width, dest.y);
-         gdk_draw_line (window, dark_gc, dest.x,
+          _cairo_draw_line (cr, dark, dest.x,
                         dest.y + (dest.height / 2),
                         dest.x + dest.width, dest.y + (dest.height / 2));
-         gdk_draw_line (window, shadow_gc, dest.x,
+          _cairo_draw_line (cr, shadow, dest.x,
                         dest.y + dest.height, dest.x + dest.width,
                         dest.y + dest.height);
        }
-
-      gdk_gc_set_clip_rectangle (shadow_gc, NULL);
-      gdk_gc_set_clip_rectangle (light_gc, NULL);
-      gdk_gc_set_clip_rectangle (dark_gc, NULL);
     }
 }
 
 static void
 draw_focus (GtkStyle *style,
-           GdkWindow *window,
+           cairo_t *cr,
            GtkStateType state_type,
-           GdkRectangle *area,
            GtkWidget *widget,
            const gchar *detail, gint x, gint y, gint width, gint height)
 {
   HDC dc;
   RECT rect;
+  XpDCInfo dc_info;
 
-  if (!GTK_WIDGET_CAN_FOCUS (widget))
+  if (!gtk_widget_get_can_focus (widget))
     {
       return;
     }
@@ -3165,27 +3207,25 @@ draw_focus (GtkStyle *style,
     {
       return;
     }
-  if (GTK_IS_TREE_VIEW (widget->parent)        /* list view bheader */
-      || GTK_IS_CLIST (widget->parent))
+  if (GTK_IS_TREE_VIEW (gtk_widget_get_parent (widget))        /* list view bheader */)
     {
       return;
     }
 
-  dc = get_window_dc (style, window, state_type, x, y, width, height, &rect);
+  dc = get_window_dc (style, cr, state_type, &dc_info, x, y, width, height, &rect);
   DrawFocusRect (dc, &rect);
-  release_window_dc (style, window, state_type);
+  release_window_dc (&dc_info);
 /*
-    parent_class->draw_focus (style, window, state_type,
-                                                    area, widget, detail, x, y, width, height);
+    parent_class->draw_focus (style, cr, state_type,
+                                                    widget, detail, x, y, width, height);
 */
 }
 
 static void
 draw_layout (GtkStyle *style,
-            GdkWindow *window,
+            cairo_t *cr,
             GtkStateType state_type,
             gboolean use_text,
-            GdkRectangle *area,
             GtkWidget *widget,
             const gchar *detail,
             gint old_x, gint old_y, PangoLayout *layout)
@@ -3200,12 +3240,12 @@ draw_layout (GtkStyle *style,
    */
   if (xp_theme_is_active () && detail && !strcmp (detail, "label"))
     {
-      if (widget->parent != NULL)
+      if (gtk_widget_get_parent (widget) != NULL)
        {
-         if (GTK_IS_NOTEBOOK (widget->parent))
+         if (GTK_IS_NOTEBOOK (gtk_widget_get_parent (widget)))
            {
              int side;
-             notebook = GTK_NOTEBOOK (widget->parent);
+             notebook = GTK_NOTEBOOK (gtk_widget_get_parent (widget));
              side = gtk_notebook_get_tab_pos (notebook);
 
              if (side == GTK_POS_TOP || side == GTK_POS_BOTTOM)
@@ -3216,8 +3256,8 @@ draw_layout (GtkStyle *style,
        }
     }
 
-  parent_class->draw_layout (style, window, state_type,
-                            use_text, area, widget, detail, x, y, layout);
+  parent_class->draw_layout (style, cr, state_type,
+                            use_text, widget, detail, x, y, layout);
 }
 
 static void
@@ -3229,163 +3269,6 @@ msw_style_init_from_rc (GtkStyle *style, GtkRcStyle *rc_style)
   parent_class->init_from_rc (style, rc_style);
 }
 
-static GdkPixmap *
-load_bg_image (GdkColormap *colormap,
-              GdkColor *bg_color, const gchar *filename)
-{
-  if (strcmp (filename, "<parent>") == 0)
-    {
-      return (GdkPixmap *) GDK_PARENT_RELATIVE;
-    }
-  else
-    {
-      return gdk_pixmap_colormap_create_from_xpm (NULL, colormap, NULL,
-                                                 bg_color, filename);
-    }
-}
-
-static void
-msw_style_realize (GtkStyle *style)
-{
-  GdkGCValues gc_values;
-  GdkGCValuesMask gc_values_mask;
-
-  gint i;
-
-  for (i = 0; i < 5; i++)
-    {
-      style->mid[i].red = (style->light[i].red + style->dark[i].red) / 2;
-      style->mid[i].green =
-       (style->light[i].green + style->dark[i].green) / 2;
-      style->mid[i].blue = (style->light[i].blue + style->dark[i].blue) / 2;
-
-      style->text_aa[i].red = (style->text[i].red + style->base[i].red) / 2;
-      style->text_aa[i].green =
-       (style->text[i].green + style->base[i].green) / 2;
-      style->text_aa[i].blue =
-       (style->text[i].blue + style->base[i].blue) / 2;
-    }
-
-  style->black.red = 0x0000;
-  style->black.green = 0x0000;
-  style->black.blue = 0x0000;
-  gdk_colormap_alloc_color (style->colormap, &style->black, FALSE, TRUE);
-
-  style->white.red = 0xffff;
-  style->white.green = 0xffff;
-  style->white.blue = 0xffff;
-  gdk_colormap_alloc_color (style->colormap, &style->white, FALSE, TRUE);
-
-  gc_values_mask = GDK_GC_FOREGROUND | GDK_GC_BACKGROUND;
-
-  gc_values.foreground = style->black;
-  gc_values.background = style->white;
-  style->black_gc =
-    gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
-
-  gc_values.foreground = style->white;
-  gc_values.background = style->black;
-  style->white_gc =
-    gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
-
-  gc_values_mask = GDK_GC_FOREGROUND;
-
-  for (i = 0; i < 5; i++)
-    {
-      if (style->rc_style && style->rc_style->bg_pixmap_name[i])
-       {
-         style->bg_pixmap[i] = load_bg_image (style->colormap,
-                                              &style->bg[i],
-                                              style->rc_style->
-                                              bg_pixmap_name[i]);
-       }
-
-      if (!gdk_colormap_alloc_color (style->colormap, &style->fg[i], FALSE, TRUE))
-       {
-         g_warning ("unable to allocate color: ( %d %d %d )", style->fg[i].red,
-                    style->fg[i].green, style->fg[i].blue);
-       }
-
-      if (!gdk_colormap_alloc_color (style->colormap, &style->bg[i], FALSE, TRUE))
-       {
-         g_warning ("unable to allocate color: ( %d %d %d )", style->bg[i].red,
-                    style->bg[i].green, style->bg[i].blue);
-       }
-
-      if (!gdk_colormap_alloc_color (style->colormap, &style->light[i], FALSE, TRUE))
-       {
-         g_warning ("unable to allocate color: ( %d %d %d )",
-                    style->light[i].red, style->light[i].green,
-                    style->light[i].blue);
-       }
-
-      if (!gdk_colormap_alloc_color (style->colormap, &style->dark[i], FALSE, TRUE))
-       {
-         g_warning ("unable to allocate color: ( %d %d %d )",
-                    style->dark[i].red, style->dark[i].green,
-                    style->dark[i].blue);
-       }
-
-      if (!gdk_colormap_alloc_color (style->colormap, &style->mid[i], FALSE, TRUE))
-       {
-         g_warning ("unable to allocate color: ( %d %d %d )",
-                    style->mid[i].red, style->mid[i].green,
-                    style->mid[i].blue);
-       }
-
-      if (!gdk_colormap_alloc_color (style->colormap, &style->text[i], FALSE, TRUE))
-       {
-         g_warning ("unable to allocate color: ( %d %d %d )",
-                    style->text[i].red, style->text[i].green,
-                    style->text[i].blue);
-       }
-
-      if (!gdk_colormap_alloc_color (style->colormap, &style->base[i], FALSE, TRUE))
-       {
-         g_warning ("unable to allocate color: ( %d %d %d )",
-                    style->base[i].red, style->base[i].green,
-                    style->base[i].blue);
-       }
-
-      if (!gdk_colormap_alloc_color (style->colormap, &style->text_aa[i], FALSE, TRUE))
-       {
-         g_warning ("unable to allocate color: ( %d %d %d )",
-                    style->text_aa[i].red, style->text_aa[i].green,
-                    style->text_aa[i].blue);
-       }
-
-      gc_values.foreground = style->fg[i];
-      style->fg_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
-
-      gc_values.foreground = style->bg[i];
-      style->bg_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
-
-      gc_values.foreground = style->light[i];
-      style->light_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
-
-      gc_values.foreground = style->dark[i];
-      style->dark_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
-
-      gc_values.foreground = style->mid[i];
-      style->mid_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
-
-      gc_values.foreground = style->text[i];
-      style->text_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
-
-      gc_values.foreground = style->base[i];
-      style->base_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
-
-      gc_values.foreground = style->text_aa[i];
-      style->text_aa_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
-    }
-}
-
-static void
-msw_style_unrealize (GtkStyle *style)
-{
-  parent_class->unrealize (style);
-}
-
 static void
 msw_style_class_init (MswStyleClass *klass)
 {
@@ -3411,9 +3294,6 @@ msw_style_class_init (MswStyleClass *klass)
   style_class->draw_slider = draw_slider;
   style_class->draw_focus = draw_focus;
   style_class->draw_layout = draw_layout;
-
-  style_class->realize = msw_style_realize;
-  style_class->unrealize = msw_style_unrealize;
 }
 
 GType msw_type_style = 0;
@@ -3421,7 +3301,7 @@ GType msw_type_style = 0;
 void
 msw_style_register_type (GTypeModule *module)
 {
-  static const GTypeInfo object_info = {
+  const GTypeInfo object_info = {
     sizeof (MswStyleClass),
     (GBaseInitFunc) NULL,
     (GBaseFinalizeFunc) NULL,