]> Pileus Git - ~andy/gtk/blobdiff - modules/engines/ms-windows/msw_style.c
Porting the MS Windows theme engine to cairo - Part 2 rectangle and line drawing
[~andy/gtk] / modules / engines / ms-windows / msw_style.c
index a7e1e63b4330d3799bf6f8160dd77b5ef6c1eb84..1105fa1cb36f92ef1b799283c4773d3a732414f5 100755 (executable)
@@ -30,6 +30,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 "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
  */
@@ -85,72 +82,72 @@ typedef enum
 
 #define PART_SIZE 13
 
-static const guint8 check_aa_bits[] = {
+static const gchar 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 guint8 check_base_bits[] = {
+static const gchar 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 guint8 check_black_bits[] = {
+static const gchar 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 guint8 check_dark_bits[] = {
+static const gchar 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 guint8 check_light_bits[] = {
+static const gchar 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 guint8 check_mid_bits[] = {
+static const gchar 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 guint8 check_text_bits[] = {
+static const gchar 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 char check_inconsistent_bits[] = {
+static const gchar 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 guint8 radio_base_bits[] = {
+static const gchar 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 guint8 radio_black_bits[] = {
+static const gchar 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 guint8 radio_dark_bits[] = {
+static const gchar 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 guint8 radio_light_bits[] = {
+static const gchar 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 guint8 radio_mid_bits[] = {
+static const gchar 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 guint8 radio_text_bits[] = {
+static const gchar 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
@@ -158,7 +155,7 @@ static const guint8 radio_text_bits[] = {
 
 static struct
 {
-  const guint8 *bits;
+  const gchar *bits;
   GdkBitmap *bmap;
 } parts[] = {
   { check_aa_bits, NULL           },
@@ -177,25 +174,67 @@ 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, LOGFONT *out_lf)
+get_system_font (XpThemeClass klazz, XpThemeFont type, LOGFONTW *out_lf)
 {
-#if 0
-  /* TODO: this causes crashes later because the font name is in UCS2, and
-     the pango fns don't deal with that gracefully */
   if (xp_theme_get_system_font (klazz, type, out_lf))
     {
       return TRUE;
     }
   else
-#endif
     {
-      NONCLIENTMETRICS ncm;
+      /* Use wide char versions here, as the theming functions only support
+       * wide chars versions of the structures. */
+      NONCLIENTMETRICSW ncm;
 
-      ncm.cbSize = sizeof (NONCLIENTMETRICS);
+      ncm.cbSize = sizeof (NONCLIENTMETRICSW);
 
-      if (SystemParametersInfo (SPI_GETNONCLIENTMETRICS,
-                               sizeof (NONCLIENTMETRICS), &ncm, 0))
+      if (SystemParametersInfoW (SPI_GETNONCLIENTMETRICS,
+                               sizeof (NONCLIENTMETRICSW), &ncm, 0))
        {
          if (type == XP_THEME_FONT_CAPTION)
            *out_lf = ncm.lfCaptionFont;
@@ -213,312 +252,56 @@ get_system_font (XpThemeClass klazz, XpThemeFont type, LOGFONT *out_lf)
   return FALSE;
 }
 
-/***************************** BEGIN STOLEN FROM PANGO *****************************/
-
-/*
-       This code is stolen from Pango 1.4. It attempts to address the following problems:
-
-       http://bugzilla.gnome.org/show_bug.cgi?id=135098
-       http://sourceforge.net/tracker/index.php?func=detail&aid=895762&group_id=76416&atid=547655
-
-       As Owen suggested in bug 135098, once Pango 1.6 is released, we need to get rid of this code.
-*/
-
-#define PING(printlist)
-
-/* TrueType defines: */
-
-#define MAKE_TT_TABLE_NAME(c1, c2, c3, c4) \
-   (((guint32)c4) << 24 | ((guint32)c3) << 16 | ((guint32)c2) << 8 | ((guint32)c1))
-
-#define CMAP (MAKE_TT_TABLE_NAME('c','m','a','p'))
-#define CMAP_HEADER_SIZE 4
-
-#define NAME (MAKE_TT_TABLE_NAME('n','a','m','e'))
-#define NAME_HEADER_SIZE 6
-
-#define ENCODING_TABLE_SIZE 8
-
-#define APPLE_UNICODE_PLATFORM_ID 0
-#define MACINTOSH_PLATFORM_ID 1
-#define ISO_PLATFORM_ID 2
-#define MICROSOFT_PLATFORM_ID 3
-
-#define SYMBOL_ENCODING_ID 0
-#define UNICODE_ENCODING_ID 1
-#define UCS4_ENCODING_ID 10
-
-struct name_header
-{
-  guint16 format_selector;
-  guint16 num_records;
-  guint16 string_storage_offset;
-};
-
-struct name_record
-{
-  guint16 platform_id;
-  guint16 encoding_id;
-  guint16 language_id;
-  guint16 name_id;
-  guint16 string_length;
-  guint16 string_offset;
-};
-
-static gboolean
-pango_win32_get_name_header (HDC hdc, struct name_header *header)
-{
-  if (GetFontData (hdc, NAME, 0, header, sizeof (*header)) != sizeof (*header))
-    return FALSE;
-
-  header->num_records = GUINT16_FROM_BE (header->num_records);
-  header->string_storage_offset = GUINT16_FROM_BE (header->string_storage_offset);
-
-  return TRUE;
-}
-
-static gboolean
-pango_win32_get_name_record (HDC hdc, gint i, struct name_record *record)
-{
-  if (GetFontData (hdc, NAME, 6 + i * sizeof (*record),
-                  record, sizeof (*record)) != sizeof (*record))
-    {
-      return FALSE;
-    }
-
-  record->platform_id = GUINT16_FROM_BE (record->platform_id);
-  record->encoding_id = GUINT16_FROM_BE (record->encoding_id);
-  record->language_id = GUINT16_FROM_BE (record->language_id);
-  record->name_id = GUINT16_FROM_BE (record->name_id);
-  record->string_length = GUINT16_FROM_BE (record->string_length);
-  record->string_offset = GUINT16_FROM_BE (record->string_offset);
-
-  return TRUE;
-}
-
-static gchar *
-get_family_name (LOGFONT *lfp, HDC pango_win32_hdc)
-{
-  HFONT hfont;
-  HFONT oldhfont;
-
-  struct name_header header;
-  struct name_record record;
-
-  gint unicode_ix = -1, mac_ix = -1, microsoft_ix = -1;
-  gint name_ix;
-  gchar *codeset;
-
-  gchar *string = NULL;
-  gchar *name;
-
-  size_t i, l, nbytes;
-
-  /* If lfFaceName is ASCII, assume it is the common (English) name for the
-     font. Is this valid? Do some TrueType fonts have different names in
-     French, German, etc, and does the system return these if the locale is
-     set to use French, German, etc? */
-  l = strlen (lfp->lfFaceName);
-  for (i = 0; i < l; i++)
-    {
-      if (lfp->lfFaceName[i] < ' ' || lfp->lfFaceName[i] > '~')
-       {
-         break;
-       }
-    }
-
-  if (i == l)
-    return g_strdup (lfp->lfFaceName);
-
-  if ((hfont = CreateFontIndirect (lfp)) == NULL)
-    goto fail0;
-
-  if ((oldhfont = (HFONT) SelectObject (pango_win32_hdc, hfont)) == NULL)
-    goto fail1;
-
-  if (!pango_win32_get_name_header (pango_win32_hdc, &header))
-    goto fail2;
-
-  PING (("%d name records", header.num_records));
-
-  for (i = 0; i < header.num_records; i++)
-    {
-      if (!pango_win32_get_name_record (pango_win32_hdc, i, &record))
-       goto fail2;
-
-      if ((record.name_id != 1 && record.name_id != 16) || record.string_length <= 0)
-       continue;
-
-      PING (("platform:%d encoding:%d language:%04x name_id:%d",
-            record.platform_id, record.encoding_id, record.language_id,
-            record.name_id));
-
-      if (record.platform_id == APPLE_UNICODE_PLATFORM_ID ||
-         record.platform_id == ISO_PLATFORM_ID)
-       {
-         unicode_ix = i;
-       }
-      else if (record.platform_id == MACINTOSH_PLATFORM_ID && record.encoding_id == 0 &&       /* Roman
-                                                                                                */
-              record.language_id == 0) /* English */
-       {
-         mac_ix = i;
-       }
-      else if (record.platform_id == MICROSOFT_PLATFORM_ID)
-       {
-         if ((microsoft_ix == -1 ||
-              PRIMARYLANGID (record.language_id) == LANG_ENGLISH) &&
-             (record.encoding_id == SYMBOL_ENCODING_ID ||
-              record.encoding_id == UNICODE_ENCODING_ID ||
-              record.encoding_id == UCS4_ENCODING_ID))
-           {
-             microsoft_ix = i;
-           }
-       }
-    }
-
-  if (microsoft_ix >= 0)
-    name_ix = microsoft_ix;
-  else if (mac_ix >= 0)
-    name_ix = mac_ix;
-  else if (unicode_ix >= 0)
-    name_ix = unicode_ix;
-  else
-    goto fail2;
-
-  if (!pango_win32_get_name_record (pango_win32_hdc, name_ix, &record))
-    goto fail2;
-
-  string = g_malloc (record.string_length + 1);
-  if (GetFontData (pango_win32_hdc, NAME,
-                  header.string_storage_offset + record.string_offset,
-                  string, record.string_length) != record.string_length)
-    goto fail2;
-
-  string[record.string_length] = '\0';
-
-  if (name_ix == microsoft_ix)
-    {
-      if (record.encoding_id == SYMBOL_ENCODING_ID ||
-         record.encoding_id == UNICODE_ENCODING_ID)
-       {
-         codeset = "UTF-16BE";
-       }
-      else
-       {
-         codeset = "UCS-4BE";
-       }
-    }
-  else if (name_ix == mac_ix)
-    {
-      codeset = "MacRoman";
-    }
-  else                         /* name_ix == unicode_ix */
-    {
-      codeset = "UCS-4BE";
-    }
-
-
-  name = g_convert (string, record.string_length, "UTF-8", codeset, NULL,
-                   &nbytes, NULL);
-  if (name == NULL)
-    goto fail2;
-
-  g_free (string);
-
-  PING (("%s", name));
-
-  SelectObject (pango_win32_hdc, oldhfont);
-  DeleteObject (hfont);
-
-  return name;
-
-fail2:
-  g_free (string);
-  SelectObject (pango_win32_hdc, oldhfont);
-
-fail1:
-  DeleteObject (hfont);
-
-fail0:
-  return g_locale_to_utf8 (lfp->lfFaceName, -1, NULL, NULL, NULL);
-}
-
-/***************************** END STOLEN FROM PANGO *****************************/
-
 static char *
 sys_font_to_pango_font (XpThemeClass klazz, XpThemeFont type, char *buf,
                        size_t bufsiz)
 {
-  HDC hDC;
-  HWND hwnd;
-  LOGFONT lf;
-  int pt_size;
-  const char *weight;
-  const char *style;
-  char *font;
+  LOGFONTW lf;
 
   if (get_system_font (klazz, type, &lf))
     {
-      switch (lf.lfWeight)
-       {
-       case FW_THIN:
-       case FW_EXTRALIGHT:
-         weight = "Ultra-Light";
-         break;
+      PangoFontDescription *desc = NULL;
+      int pt_size;
+      const char *font;
 
-       case FW_LIGHT:
-         weight = "Light";
-         break;
+      desc = pango_win32_font_description_from_logfontw (&lf);
+      if (!desc)
+       return NULL;
 
-       case FW_BOLD:
-         weight = "Bold";
-         break;
+      font = pango_font_description_to_string (desc);
+      pt_size = pango_font_description_get_size (desc);
 
-       case FW_SEMIBOLD:
-         weight = "Semi-Bold";
-         break;
+      if (!(font && *font))
+       {
+         pango_font_description_free (desc);
+         return NULL;
+       }
 
-       case FW_ULTRABOLD:
-         weight = "Ultra-Bold";
-         break;
+      if (pt_size == 0)
+       {
+         HDC hDC;
+         HWND hwnd;
 
-       case FW_HEAVY:
-         weight = "Heavy";
-         break;
+         hwnd = GetDesktopWindow ();
+         hDC = GetDC (hwnd);
 
-       default:
-         weight = "";
-         break;
-       }
+         if (hDC)
+           pt_size = -MulDiv (lf.lfHeight, 72, GetDeviceCaps (hDC, LOGPIXELSY));
+         else
+           pt_size = 10;
 
-      if (lf.lfItalic)
-       style = "Italic";
-      else
-       style = "";
+         if (hDC)
+           ReleaseDC (hwnd, hDC);
 
-      hwnd = GetDesktopWindow ();
-      hDC = GetDC (hwnd);
-      if (hDC)
-       {
-         pt_size = -MulDiv (lf.lfHeight, 72,
-                            GetDeviceCaps (hDC, LOGPIXELSY));
+         g_snprintf (buf, bufsiz, "%s %d", font, pt_size);
        }
       else
        {
-         pt_size = 10;
+         g_snprintf (buf, bufsiz, "%s", font);
        }
 
-      font = get_family_name (&lf, hDC);
-
-      if (hDC)
-       ReleaseDC (hwnd, hDC);
-
-      if (!(font && *font))
-       return NULL;
-
-      g_snprintf (buf, bufsiz, "%s %s %s %d", font, style, weight, pt_size);
-      g_free (font);
+      if (desc)
+       pango_font_description_free (desc);
 
       return buf;
     }
@@ -568,7 +351,6 @@ static void
 setup_menu_settings (GtkSettings *settings)
 {
   int menu_delay;
-  OSVERSIONINFOEX osvi;
   GObjectClass *klazz = G_OBJECT_GET_CLASS (G_OBJECT (settings));
 
   if (get_windows_version () > WIN95_VERSION)
@@ -1011,7 +793,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->bg[GTK_STATE_ACTIVE]);
   sys_color_to_gtk_color (XP_THEME_CLASS_WINDOW, COLOR_WINDOWTEXT,
                          &style->fg[GTK_STATE_PRELIGHT]);
 
@@ -1062,7 +844,7 @@ map_gtk_progress_bar_to_xp (GtkProgressBar *progress_bar, gboolean trough)
 {
   XpThemeElement ret;
 
-  switch (progress_bar->orientation)
+  switch (gtk_progress_bar_get_orientation (progress_bar))
     {
     case GTK_PROGRESS_LEFT_TO_RIGHT:
     case GTK_PROGRESS_RIGHT_TO_LEFT:
@@ -1113,8 +895,9 @@ 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, window, state, &dc_info, area->x, area->y, area->width,
                          area->height, &rect);
       border = (GTK_TOGGLE_BUTTON (widget->parent)->
                active ? DFCS_PUSHED | DFCS_FLAT : 0);
@@ -1122,7 +905,7 @@ combo_box_draw_arrow (GtkStyle *style,
       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;
     }
@@ -1172,8 +955,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 (window, &style->black, area, x, y, CHECK_TEXT);
+          draw_part (window, &style->dark[state], area, x, y, CHECK_AA);
        }
     }
   else
@@ -1199,24 +982,24 @@ draw_check (GtkStyle *style,
          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 (window, &style->black, area, x, y, CHECK_BLACK);
+          draw_part (window, &style->dark[state], area, x, y, CHECK_DARK);
+          draw_part (window, &style->mid[state], area, x, y, CHECK_MID);
+          draw_part (window, &style->light[state], area, x, y, CHECK_LIGHT);
+          draw_part (window, &style->base[state], area, x, y, CHECK_BASE);
 
          if (shadow == GTK_SHADOW_IN)
            {
-             draw_part (window, style->text_gc[state], area, x,
+              draw_part (window, &style->text[state], area, x,
                         y, CHECK_TEXT);
-             draw_part (window, style->text_aa_gc[state], area,
+              draw_part (window, &style->text_aa[state], area,
                         x, y, CHECK_AA);
            }
          else if (shadow == GTK_SHADOW_ETCHED_IN)
            {
-             draw_part (window, style->text_gc[state], area, x, y,
+              draw_part (window, &style->text[state], area, x, y,
                         CHECK_INCONSISTENT);
-             draw_part (window, style->text_aa_gc[state], area, x, y,
+              draw_part (window, &style->text_aa[state], area, x, y,
                         CHECK_AA);
            }
        }
@@ -1232,6 +1015,8 @@ draw_expander (GtkStyle *style,
               const gchar *detail,
               gint x, gint y, GtkExpanderStyle expander_style)
 {
+  cairo_t *cr = gdk_cairo_create (window);
+
   gint expander_size;
   gint expander_semi_size;
   XpThemeElement xp_expander;
@@ -1257,7 +1042,11 @@ draw_expander (GtkStyle *style,
     expander_size -= 2;
 
   if (area)
-    gdk_gc_set_clip_rectangle (style->fg_gc[state], area);
+    {
+      gdk_cairo_rectangle (cr, area);
+      cairo_clip (cr);
+      gdk_cairo_set_source_color (cr, &style->fg[state]);
+    }
 
   expander_semi_size = expander_size / 2;
   x -= expander_semi_size;
@@ -1270,8 +1059,9 @@ draw_expander (GtkStyle *style,
       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, window, state, &dc_info, x, y, expander_size,
                          expander_size, &rect);
       FrameRect (dc, &rect, GetSysColorBrush (COLOR_GRAYTEXT));
       InflateRect (&rect, -1, -1);
@@ -1297,11 +1087,10 @@ 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);
+  cairo_destroy(cr);
 }
 
 static void
@@ -1320,7 +1109,7 @@ draw_option (GtkStyle *style,
     {
       if (shadow == GTK_SHADOW_IN)
        {
-         draw_part (window, style->fg_gc[state], area, x, y, RADIO_TEXT);
+          draw_part (window, &style->fg[state], area, x, y, RADIO_TEXT);
        }
     }
   else
@@ -1336,21 +1125,21 @@ 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 (window, &style->black, area, x, y, RADIO_BLACK);
+          draw_part (window, &style->dark[state], area, x, y, RADIO_DARK);
+          draw_part (window, &style->mid[state], area, x, y, RADIO_MID);
+          draw_part (window, &style->light[state], area, x, y, RADIO_LIGHT);
+          draw_part (window, &style->base[state], area, x, y, RADIO_BASE);
 
          if (shadow == GTK_SHADOW_IN)
-           draw_part (window, style->text_gc[state], area, x, y, RADIO_TEXT);
+            draw_part (window, &style->text[state], area, x, y, RADIO_TEXT);
        }
     }
 }
 
 static void
 draw_varrow (GdkWindow *window,
-            GdkGC *gc,
+             GdkColor *gc,
             GtkShadowType shadow_type,
             GdkRectangle *area,
             GtkArrowType arrow_type, gint x, gint y, gint width, gint height)
@@ -1358,9 +1147,15 @@ draw_varrow (GdkWindow *window,
   gint steps, extra;
   gint y_start, y_increment;
   gint i;
+  cairo_t *cr;
+  
+  cr = gdk_cairo_create (window);
 
   if (area)
-    gdk_gc_set_clip_rectangle (gc, area);
+    {
+       gdk_cairo_rectangle (cr, area);
+       cairo_clip (cr);
+    }
 
   width = width + width % 2 - 1;       /* Force odd */
   steps = 1 + width / 2;
@@ -1379,18 +1174,17 @@ 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);
+  cairo_destroy(cr);
 }
 
 static void
 draw_harrow (GdkWindow *window,
-            GdkGC *gc,
+             GdkColor *gc,
             GtkShadowType shadow_type,
             GdkRectangle *area,
             GtkArrowType arrow_type, gint x, gint y, gint width, gint height)
@@ -1398,9 +1192,15 @@ draw_harrow (GdkWindow *window,
   gint steps, extra;
   gint x_start, x_increment;
   gint i;
+  cairo_t *cr;
+  
+  cr = gdk_cairo_create (window);
 
   if (area)
-    gdk_gc_set_clip_rectangle (gc, area);
+    {
+       gdk_cairo_rectangle (cr, area);
+       cairo_clip (cr);
+    }
 
   height = height + height % 2 - 1;    /* Force odd */
   steps = 1 + height / 2;
@@ -1419,14 +1219,12 @@ 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);
+  cairo_destroy(cr);
 }
 
 /* This function makes up for some brokeness in gtkrange.c
@@ -1510,6 +1308,7 @@ draw_arrow (GtkStyle *style,
   const gchar *name;
   HDC dc;
   RECT rect;
+  XpDCInfo dc_info;
 
   name = gtk_widget_get_name (widget);
 
@@ -1537,7 +1336,7 @@ draw_arrow (GtkStyle *style,
          ++y;
        }
 
-      draw_varrow (window, style->fg_gc[state], shadow, area,
+      draw_varrow (window, &style->fg[state], shadow, area,
                   arrow_type, x, y, width, height);
 
       return;
@@ -1557,9 +1356,9 @@ 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_range_get_adjustment(&scrollbar->range)->page_size >=
+          (gtk_range_get_adjustment(&scrollbar->range)->upper -
+           gtk_range_get_adjustment(&scrollbar->range)->lower))
        {
          is_disabled = TRUE;
        }
@@ -1601,13 +1400,13 @@ draw_arrow (GtkStyle *style,
            {
              sanitize_size (window, &width, &height);
 
-             dc = get_window_dc (style, window, state,
+             dc = get_window_dc (style, window, 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);
            }
        }
     }
@@ -1641,7 +1440,7 @@ draw_arrow (GtkStyle *style,
          x += (width - 7) / 2;
          y += (height - 5) / 2;
 
-         draw_varrow (window, style->fg_gc[state], shadow, area,
+          draw_varrow (window, &style->fg[state], shadow, area,
                       arrow_type, x, y, 7, 5);
        }
       else
@@ -1649,7 +1448,7 @@ draw_arrow (GtkStyle *style,
          x += (width - 5) / 2;
          y += (height - 7) / 2;
 
-         draw_harrow (window, style->fg_gc[state], shadow, area,
+          draw_harrow (window, &style->fg[state], shadow, area,
                       arrow_type, x, y, 5, 7);
        }
     }
@@ -1716,50 +1515,6 @@ is_menu_tool_button_child (GtkWidget *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 ()
 {
@@ -1823,6 +1578,7 @@ draw_menu_item (GdkWindow *window, GtkWidget *widget, GtkStyle *style,
   GtkMenuShell *bar;
   HDC dc;
   RECT rect;
+  XpDCInfo dc_info;
 
   if (xp_theme_is_active ())
     {
@@ -1835,14 +1591,14 @@ draw_menu_item (GdkWindow *window, GtkWidget *widget, GtkStyle *style,
     {
       bar = GTK_MENU_SHELL (parent);
 
-      dc = get_window_dc (style, window, state_type, x, y, width, height, &rect);
+      dc = get_window_dc (style, window, state_type, &dc_info, x, y, width, height, &rect);
 
       if (state_type == GTK_STATE_PRELIGHT)
        {
          draw_3d_border (dc, &rect, bar->active);
        }
 
-      release_window_dc (style, window, state_type);
+      release_window_dc (&dc_info);
 
       return TRUE;
     }
@@ -1883,6 +1639,7 @@ draw_tool_button (GdkWindow *window, GtkWidget *widget, GtkStyle *style,
 {
   HDC dc;
   RECT rect;
+  XpDCInfo dc_info;
   gboolean is_toggled = FALSE;
 
   if (xp_theme_is_active ())
@@ -1905,7 +1662,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, window, state_type, &dc_info, x, y, width, height, &rect);
   if (state_type == GTK_STATE_PRELIGHT)
     {
       if (is_toggled)
@@ -1927,7 +1684,7 @@ 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;
 }
@@ -1939,8 +1696,9 @@ draw_push_button (GdkWindow *window, GtkWidget *widget, GtkStyle *style,
 {
   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, window, state_type, &dc_info, x, y, width, height, &rect);
 
   if (GTK_IS_TOGGLE_BUTTON (widget))
     {
@@ -1971,7 +1729,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);
@@ -1980,7 +1738,7 @@ 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
@@ -1995,15 +1753,16 @@ draw_box (GtkStyle *style,
   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);
 
-      dc = get_window_dc (style, window, state_type, x, y, width, height, &rect);
+      dc = get_window_dc (style, window, 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,
@@ -2014,9 +1773,9 @@ draw_box (GtkStyle *style,
       width = cx;
 
 
-      dc = get_window_dc (style, window, state_type, x, y, width - cx, height, &rect);
+      dc = get_window_dc (style, window, 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;
        }
     }
@@ -2024,7 +1783,7 @@ 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 (widget->parent))
       {
         if (xp_theme_draw
              (window, XP_THEME_ELEMENT_LIST_HEADER, style, x, y,
@@ -2036,13 +1795,14 @@ 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, window, 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)
@@ -2092,14 +1852,15 @@ draw_box (GtkStyle *style,
                          style, x, y, width, height, state_type, area))
        {
          RECT rect;
+         XpDCInfo dc_info;
          HDC dc;
 
-         dc = get_window_dc (style, window, state_type,
+         dc = get_window_dc (style, window, 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;
     }
@@ -2139,9 +1900,9 @@ draw_box (GtkStyle *style,
            }
          else
            {
-             if (scrollbar->range.adjustment->page_size >=
-                 (scrollbar->range.adjustment->upper -
-                  scrollbar->range.adjustment->lower))
+              if (gtk_range_get_adjustment(&scrollbar->range)->page_size >=
+                 (gtk_range_get_adjustment(&scrollbar->range)->upper -
+                  gtk_range_get_adjustment(&scrollbar->range)->lower))
                {
                  return;
                }
@@ -2208,15 +1969,16 @@ 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, window, 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;
            }
@@ -2301,8 +2063,6 @@ 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))
        {
@@ -2326,9 +2086,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, window, state_type, &dc_info, x, y, width, height, &rect);
 
              brush = GetSysColorBrush (COLOR_3DDKSHADOW);
 
@@ -2340,7 +2101,7 @@ 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;
            }
@@ -2415,7 +2176,7 @@ draw_tab (GtkStyle *style,
 
   y += (height - arrow_height) / 2;
 
-  draw_varrow (window, style->black_gc, shadow, area, GTK_ARROW_DOWN,
+  draw_varrow (window, &style->black, shadow, area, GTK_ARROW_DOWN,
               x, y, indicator_size.width, arrow_height);
 }
 
@@ -2545,6 +2306,7 @@ draw_themed_tab_button (GtkStyle *style,
   GtkWidget *widget = GTK_WIDGET (notebook);
   GdkRectangle draw_rect, clip_rect;
   GdkPixbufRotation rotation = GDK_PIXBUF_ROTATE_NONE;
+  cairo_t *cr;
 
   if (gap_side == GTK_POS_TOP)
     {
@@ -2748,9 +2510,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);
+      cr = gdk_cairo_create (window);
+      gdk_cairo_set_source_pixbuf (cr, pixbuf, clip_rect.x, clip_rect.y);
+      cairo_paint (cr);
+      cairo_destroy (cr);
       g_object_unref (pixbuf);
     }
 
@@ -2771,10 +2534,13 @@ draw_tab_button (GtkStyle *style,
     {
       /* experimental tab-drawing code from mozilla */
       RECT rect;
+      XpDCInfo dc_info;
       HDC dc;
       gint32 aPosition;
+         cairo_t *cr;
 
-      dc = get_window_dc (style, window, state_type, x, y, width, height, &rect);
+      dc = get_window_dc (style, window, state_type, &dc_info, x, y, width, height, &rect);
+         cr = gdk_cairo_create (window);
 
       if (gap_side == GTK_POS_TOP)
        aPosition = BF_TOP;
@@ -2788,16 +2554,19 @@ 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);
+        {
+           gdk_cairo_rectangle (cr, area);
+           cairo_clip (cr);
+           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);
+      cairo_destroy (cr);
 
-      release_window_dc (style, window, state_type);
+      release_window_dc (&dc_info);
       return TRUE;
     }
 
@@ -2855,29 +2624,29 @@ 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;
        }
 
@@ -2925,9 +2694,12 @@ draw_flat_box (GtkStyle *style, GdkWindow *window,
       if (state_type == GTK_STATE_SELECTED &&
          (!strncmp ("cell_even", detail, 9) || !strncmp ("cell_odd", detail, 8)))
        {
-         GdkGC *gc = GTK_WIDGET_HAS_FOCUS (widget) ? style->base_gc[state_type] : style->base_gc[GTK_STATE_ACTIVE];
+          GdkColor *gc = gtk_widget_has_focus (widget) ? &style->base[state_type] : &style->base[GTK_STATE_ACTIVE];
+          cairo_t *cr = gdk_cairo_create (window);
+
+          _cairo_draw_rectangle (cr, gc, TRUE, x, y, width, height);
 
-         gdk_draw_rectangle (window, gc, TRUE, x, y, width, height);
+                 cairo_destroy (cr);
 
          return;
        }
@@ -2949,9 +2721,10 @@ draw_menu_border (GdkWindow *win, 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, win, GTK_STATE_NORMAL, &dc_info, x, y, width, height, &rect);
 
   if (!dc)
     return FALSE;
@@ -2965,7 +2738,7 @@ 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;
 }
@@ -2987,10 +2760,11 @@ draw_shadow (GtkStyle *style,
 
       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, window, state_type, &dc_info, x, y, width, height, &rect);
       if (is_combo_box_child (widget))
         {
           FillRect (dc, &rect, GetSysColorBrush (COLOR_WINDOW));
@@ -3028,7 +2802,7 @@ draw_shadow (GtkStyle *style,
            }
        }
 
-      release_window_dc (style, window, state_type);
+      release_window_dc (&dc_info);
 
       return;
     }
@@ -3042,12 +2816,13 @@ draw_shadow (GtkStyle *style,
        {
          HDC dc;
          RECT rect;
+         XpDCInfo dc_info;
 
-         dc = get_window_dc (style, window, state_type,
+         dc = get_window_dc (style, window, 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;
@@ -3090,6 +2865,7 @@ draw_shadow (GtkStyle *style,
        {
          HDC dc;
          RECT rect;
+         XpDCInfo dc_info;
          HGDIOBJ old_pen = NULL;
          GtkPositionType pos;
 
@@ -3142,7 +2918,7 @@ draw_shadow (GtkStyle *style,
                }
            }
 
-         dc = get_window_dc (style, window, state_type, x, y, width, height, &rect);
+         dc = get_window_dc (style, window, state_type, &dc_info, x, y, width, height, &rect);
 
          if (pos != GTK_POS_LEFT)
            {
@@ -3170,7 +2946,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;
@@ -3193,10 +2969,27 @@ draw_hline (GtkStyle *style,
            GtkWidget *widget,
            const gchar *detail, gint x1, gint x2, gint y)
 {
+  cairo_t *cr;
+  
+  cr = gdk_cairo_create (window);
+
   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 = (area->height / 2) - (cy / 2);
+      new_y = y_offset >= 0 ? area->y + y_offset : area->y;
+      new_height = cy;
+
       if (xp_theme_draw
-         (window, XP_THEME_ELEMENT_MENU_SEPARATOR, style, x1, y, x2, 1,
+         (window, XP_THEME_ELEMENT_MENU_SEPARATOR, style, x1, new_y, x2, new_height,
           state_type, area))
        {
          return;
@@ -3205,15 +2998,12 @@ draw_hline (GtkStyle *style,
        {
          if (area)
            {
-             gdk_gc_set_clip_rectangle (style->dark_gc[state_type], area);
+              gdk_cairo_rectangle (cr, area);
+              cairo_clip (cr);
            }
 
-         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
@@ -3222,19 +3012,14 @@ draw_hline (GtkStyle *style,
        {
          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_cairo_rectangle (cr, area);
+              cairo_clip (cr);
            }
 
-         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
        {
@@ -3242,6 +3027,7 @@ draw_hline (GtkStyle *style,
                                    detail, x1, x2, y);
        }
     }
+  cairo_destroy (cr);
 }
 
 static void
@@ -3252,29 +3038,30 @@ draw_vline (GtkStyle *style,
            GtkWidget *widget,
            const gchar *detail, gint y1, gint y2, gint x)
 {
+  cairo_t *cr;
+  
+  cr = gdk_cairo_create (window);
+
   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_cairo_rectangle (cr, area);
+              cairo_clip (cr);
        }
 
-      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,
                                detail, y1, y2, x);
     }
+
+  cairo_destroy (cr);
 }
 
 static void
@@ -3311,28 +3098,36 @@ draw_resize_grip (GtkStyle *style,
                  const gchar *detail,
                  GdkWindowEdge edge, gint x, gint y, gint width, gint height)
 {
+  cairo_t *cr;
+  
+  cr = gdk_cairo_create (window);
+  
   if (detail && !strcmp (detail, "statusbar"))
     {
       if (xp_theme_draw
          (window, XP_THEME_ELEMENT_STATUS_GRIPPER, style, x, y, width,
           height, state_type, area))
        {
+          cairo_destroy (cr);
          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, window, state_type, &dc_info, x, y, width, height, &rect);
 
          if (area)
-           gdk_gc_set_clip_rectangle (style->dark_gc[state_type], area);
+            {
+              gdk_cairo_rectangle (cr, area);
+              cairo_clip (cr);
+              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);
 
+          cairo_destroy (cr);
          return;
        }
     }
@@ -3354,6 +3149,10 @@ draw_handle (GtkStyle *style,
 {
   HDC dc;
   RECT rect;
+  XpDCInfo dc_info;
+  cairo_t *cr;
+  
+  cr = gdk_cairo_create (window);
 
   if (is_toolbar_child (widget))
     {
@@ -3387,7 +3186,7 @@ draw_handle (GtkStyle *style,
          return;
        }
 
-      dc = get_window_dc (style, window, state_type, x, y, width, height, &rect);
+      dc = get_window_dc (style, window, state_type, &dc_info, x, y, width, height, &rect);
 
       if (orientation == GTK_ORIENTATION_VERTICAL)
        {
@@ -3405,14 +3204,14 @@ 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);
@@ -3420,9 +3219,9 @@ draw_handle (GtkStyle *style,
       gtk_paint_box (style, window, state_type, shadow_type, area,
                     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;
@@ -3437,34 +3236,31 @@ 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);
+      gdk_cairo_rectangle (cr, &dest);
+      cairo_clip (cr);
 
       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);
+      cairo_destroy (cr);
     }
 }
 
@@ -3478,6 +3274,7 @@ draw_focus (GtkStyle *style,
 {
   HDC dc;
   RECT rect;
+  XpDCInfo dc_info;
 
   if (!gtk_widget_get_can_focus (widget))
     {
@@ -3489,15 +3286,14 @@ 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 (widget->parent)        /* list view bheader */)
     {
       return;
     }
 
-  dc = get_window_dc (style, window, state_type, x, y, width, height, &rect);
+  dc = get_window_dc (style, window, 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);
@@ -3553,163 +3349,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)
 {
@@ -3735,9 +3374,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;