[gtk+] win32: Fix the xp there to correctly clip when drawing



commit 4696e941385d03af05cbfc1aaecea72b8bab7696
Author: Martin Schlemmer <11285613 nwu ac za>
Date:   Fri Jun 11 20:20:07 2010 +0200

    win32: Fix the xp there to correctly clip when drawing
    
    This makes the xp theme work again, and also enables it.

 gdk/gdk.symbols                        |    8 ++
 gdk/gdkinternals.h                     |    8 ++
 gdk/gdkwindow.c                        |  105 ++++++++++++++++++++++
 gdk/win32/gdkwin32.h                   |    8 ++
 gdk/win32/gdkwindow-win32.c            |   24 +++++
 modules/engines/ms-windows/msw_style.c |  149 +++++++++++++-------------------
 modules/engines/ms-windows/xp_theme.c  |   80 +++++++++++------
 modules/engines/ms-windows/xp_theme.h  |   20 ++++
 8 files changed, 283 insertions(+), 119 deletions(-)
---
diff --git a/gdk/gdk.symbols b/gdk/gdk.symbols
index 7b25c6e..e7f9462 100644
--- a/gdk/gdk.symbols
+++ b/gdk/gdk.symbols
@@ -1209,6 +1209,14 @@ gdk_window_destroy_notify
 
 #ifdef GDK_WINDOWING_WIN32
 #if IN_HEADER(__GDK_WIN32_H__)
+#if IN_FILE(__GDK_WINDOW_WIN32_C__)
+gdk_win32_begin_direct_draw_libgtk_only
+gdk_win32_end_direct_draw_libgtk_only
+#endif
+#endif
+
+#ifdef GDK_WINDOWING_WIN32
+#if IN_HEADER(__GDK_WIN32_H__)
 #if IN_FILE(__GDK_WIN32ID_C__)
 gdk_win32_handle_table_lookup
 #endif
diff --git a/gdk/gdkinternals.h b/gdk/gdkinternals.h
index b154c57..01d3f88 100644
--- a/gdk/gdkinternals.h
+++ b/gdk/gdkinternals.h
@@ -439,6 +439,14 @@ void       _gdk_gc_set_clip_region_internal (GdkGC     *gc,
 					     gboolean reset_origin);
 GdkSubwindowMode _gdk_gc_get_subwindow (GdkGC *gc);
 
+GdkDrawable *_gdk_drawable_begin_direct_draw (GdkDrawable *drawable,
+					      GdkGC *gc,
+					      gpointer *priv_data,
+					      gint *x_offset_out,
+					      gint *y_offset_out);
+void         _gdk_drawable_end_direct_draw (gpointer priv_data);
+
+
 /*****************************************
  * Interfaces provided by windowing code *
  *****************************************/
diff --git a/gdk/gdkwindow.c b/gdk/gdkwindow.c
index af76377..a985ef3 100644
--- a/gdk/gdkwindow.c
+++ b/gdk/gdkwindow.c
@@ -3844,6 +3844,111 @@ start_draw_helper (GdkDrawable *drawable,
      }                                                      \
   }
 
+#define BEGIN_DRAW_MACRO \
+  {
+
+#define END_DRAW_MACRO \
+  }
+
+typedef struct
+{
+  GdkDrawable *drawable;
+  GdkGC *gc;
+
+  gint x_offset;
+  gint y_offset;
+
+  gint clip_x;
+  gint clip_y;
+  gint ts_x;
+  gint ts_y;
+} DirectDrawInfo;
+
+GdkDrawable *
+_gdk_drawable_begin_direct_draw (GdkDrawable *drawable,
+				 GdkGC *gc,
+				 gpointer *priv_data,
+				 gint *x_offset_out,
+				 gint *y_offset_out)
+{
+  g_return_val_if_fail (priv_data != NULL, NULL);
+
+  GdkDrawable *out_impl = NULL;
+
+  *priv_data = NULL;
+
+  if (GDK_IS_PIXMAP (drawable))
+    {
+      /* We bypass the GdkPixmap functions, so do this ourself */
+      _gdk_gc_remove_drawable_clip (gc);
+
+      out_impl = drawable;
+
+      *x_offset_out = 0;
+      *y_offset_out = 0;
+    }
+  else
+    {
+      if (GDK_WINDOW_DESTROYED (drawable))
+        return NULL;
+
+      BEGIN_DRAW;
+
+      if (impl == NULL)
+        return NULL;
+
+      out_impl = impl;
+
+      *x_offset_out = x_offset;
+      *y_offset_out = y_offset;
+
+      DirectDrawInfo *priv = g_new (DirectDrawInfo, 1);
+
+      priv->drawable = impl;
+      priv->gc = gc;
+
+      priv->x_offset = x_offset;
+      priv->y_offset = y_offset;
+      priv->clip_x = old_clip_x;
+      priv->clip_y = old_clip_y;
+      priv->ts_x = old_ts_x;
+      priv->ts_y = old_ts_y;
+
+      *priv_data = (gpointer) priv;
+
+      END_DRAW_MACRO;
+    }
+
+  return out_impl;
+}
+
+void
+_gdk_drawable_end_direct_draw (gpointer priv_data)
+{
+  /* Its a GdkPixmap or the call to _gdk_drawable_begin_direct_draw failed. */
+  if (priv_data == NULL)
+    return;
+
+  DirectDrawInfo *priv = priv_data;
+  GdkGC *gc = priv->gc;
+
+  /* This is only for GdkWindows - if GdkPixmaps need any handling here in
+   * the future, then we should keep track of what type of drawable it is in
+   * DirectDrawInfo. */
+  BEGIN_DRAW_MACRO;
+
+  gint x_offset = priv->x_offset;
+  gint y_offset = priv->y_offset;
+  gint old_clip_x = priv->clip_x;
+  gint old_clip_y = priv->clip_y;
+  gint old_ts_x = priv->ts_x;
+  gint old_ts_y = priv->ts_y;
+
+  END_DRAW;
+
+  g_free (priv_data);
+}
+
 static GdkGC *
 gdk_window_create_gc (GdkDrawable     *drawable,
 		      GdkGCValues     *values,
diff --git a/gdk/win32/gdkwin32.h b/gdk/win32/gdkwin32.h
index 401bca8..34fc537 100644
--- a/gdk/win32/gdkwin32.h
+++ b/gdk/win32/gdkwin32.h
@@ -105,6 +105,14 @@ GdkPixbuf    *gdk_win32_icon_to_pixbuf_libgtk_only (HICON hicon);
 HICON         gdk_win32_pixbuf_to_hicon_libgtk_only (GdkPixbuf *pixbuf);
 void          gdk_win32_set_modal_dialog_libgtk_only (HWND window);
 
+GdkDrawable  *gdk_win32_begin_direct_draw_libgtk_only (GdkDrawable *drawable,
+						       GdkGC *gc,
+						       gpointer *priv_data,
+						       gint *x_offset_out,
+						       gint *y_offset_out);
+void          gdk_win32_end_direct_draw_libgtk_only (gpointer priv_data);
+
+
 G_END_DECLS
 
 #endif /* __GDK_WIN32_H__ */
diff --git a/gdk/win32/gdkwindow-win32.c b/gdk/win32/gdkwindow-win32.c
index d44d8f4..9161f6f 100644
--- a/gdk/win32/gdkwindow-win32.c
+++ b/gdk/win32/gdkwindow-win32.c
@@ -3377,3 +3377,27 @@ gdk_window_impl_iface_init (GdkWindowImplIface *iface)
   iface->queue_translation = _gdk_win32_window_queue_translation;
   iface->destroy = _gdk_win32_window_destroy;
 }
+
+GdkDrawable *
+gdk_win32_begin_direct_draw_libgtk_only (GdkDrawable *drawable,
+					 GdkGC *gc,
+					 gpointer *priv_data,
+					 gint *x_offset_out,
+					 gint *y_offset_out)
+{
+  GdkDrawable *impl;
+
+  impl = _gdk_drawable_begin_direct_draw (drawable,
+					  gc,
+					  priv_data,
+					  x_offset_out,
+					  y_offset_out);
+
+  return impl;
+}
+
+void
+gdk_win32_end_direct_draw_libgtk_only (gpointer priv_data)
+{
+  _gdk_drawable_end_direct_draw (priv_data);
+}
diff --git a/modules/engines/ms-windows/msw_style.c b/modules/engines/ms-windows/msw_style.c
index b9fb0dd..26106e7 100755
--- a/modules/engines/ms-windows/msw_style.c
+++ b/modules/engines/ms-windows/msw_style.c
@@ -47,12 +47,6 @@
 #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
  */
@@ -1113,8 +1107,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 +1117,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;
     }
@@ -1270,8 +1265,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,7 +1293,7 @@ draw_expander (GtkStyle *style,
 
       SelectObject (dc, old_pen);
       DeleteObject (pen);
-      release_window_dc (style, window, state);
+      release_window_dc (&dc_info);
     }
 
   if (area)
@@ -1510,6 +1506,7 @@ draw_arrow (GtkStyle *style,
   const gchar *name;
   HDC dc;
   RECT rect;
+  XpDCInfo dc_info;
 
   name = gtk_widget_get_name (widget);
 
@@ -1601,13 +1598,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);
 	    }
 	}
     }
@@ -1716,50 +1713,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 +1776,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 +1789,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 +1837,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 +1860,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 +1882,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 +1894,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))
     {
@@ -1980,7 +1936,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 +1951,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 +1971,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;
 	}
     }
@@ -2036,13 +1993,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 +2050,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;
     }
@@ -2208,15 +2167,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;
 	    }
@@ -2326,9 +2286,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 +2301,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;
 	    }
@@ -2771,10 +2732,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, window, state_type, &dc_info, x, y, width, height, &rect);
 
       if (gap_side == GTK_POS_TOP)
 	aPosition = BF_TOP;
@@ -2797,7 +2759,7 @@ draw_tab_button (GtkStyle *style,
       if (area)
 	gdk_gc_set_clip_rectangle (style->dark_gc[state_type], NULL);
 
-      release_window_dc (style, window, state_type);
+      release_window_dc (&dc_info);
       return TRUE;
     }
 
@@ -2949,9 +2911,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 +2928,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 +2950,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 +2992,7 @@ draw_shadow (GtkStyle *style,
 	    }
 	}
 
-      release_window_dc (style, window, state_type);
+      release_window_dc (&dc_info);
 
       return;
     }
@@ -3042,12 +3006,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 +3055,7 @@ draw_shadow (GtkStyle *style,
 	{
 	  HDC dc;
 	  RECT rect;
+	  XpDCInfo dc_info;
 	  HGDIOBJ old_pen = NULL;
 	  GtkPositionType pos;
 
@@ -3142,7 +3108,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 +3136,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;
@@ -3322,13 +3288,14 @@ draw_resize_grip (GtkStyle *style,
       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);
 
 	  DrawFrameControl (dc, &rect, DFC_SCROLL, DFCS_SCROLLSIZEGRIP);
-	  release_window_dc (style, window, state_type);
+	  release_window_dc (&dc_info);
 
 	  if (area)
 	    gdk_gc_set_clip_rectangle (style->dark_gc[state_type], NULL);
@@ -3354,6 +3321,7 @@ draw_handle (GtkStyle *style,
 {
   HDC dc;
   RECT rect;
+  XpDCInfo dc_info;
 
   if (is_toolbar_child (widget))
     {
@@ -3387,7 +3355,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,7 +3373,7 @@ draw_handle (GtkStyle *style,
 	}
 
       draw_3d_border (dc, &rect, FALSE);
-      release_window_dc (style, window, state_type);
+      release_window_dc (&dc_info);
       return;
     }
 
@@ -3478,6 +3446,7 @@ draw_focus (GtkStyle *style,
 {
   HDC dc;
   RECT rect;
+  XpDCInfo dc_info;
 
   if (!gtk_widget_get_can_focus (widget))
     {
@@ -3494,9 +3463,9 @@ draw_focus (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);
   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);
diff --git a/modules/engines/ms-windows/xp_theme.c b/modules/engines/ms-windows/xp_theme.c
index 3d11935..d217295 100755
--- a/modules/engines/ms-windows/xp_theme.c
+++ b/modules/engines/ms-windows/xp_theme.c
@@ -849,6 +849,47 @@ xp_theme_map_gtk_state (XpThemeElement element, GtkStateType state)
   return ret;
 }
 
+HDC
+get_window_dc (GtkStyle *style,
+	       GdkWindow *window,
+	       GtkStateType state_type,
+	       XpDCInfo *dc_info_out,
+	       gint x, gint y, gint width, gint height,
+	       RECT *rect_out)
+{
+  GdkDrawable *drawable = NULL;
+  GdkGC *gc = style->dark_gc[state_type];
+  gint x_offset, y_offset;
+  
+  dc_info_out->data = NULL;
+  
+  drawable = gdk_win32_begin_direct_draw_libgtk_only (window,
+						      gc, &dc_info_out->data,
+						      &x_offset, &y_offset);
+  if (!drawable)
+    return NULL;
+
+  rect_out->left = x - x_offset;
+  rect_out->top = y - y_offset;
+  rect_out->right = rect_out->left + width;
+  rect_out->bottom = rect_out->top + height;
+  
+  dc_info_out->drawable = drawable;
+  dc_info_out->gc = gc;
+  dc_info_out->x_offset = x_offset;
+  dc_info_out->y_offset = y_offset;
+  
+  return gdk_win32_hdc_get (drawable, gc, 0);
+}
+
+void
+release_window_dc (XpDCInfo *dc_info)
+{
+  gdk_win32_hdc_release (dc_info->drawable, dc_info->gc, 0);
+
+  gdk_win32_end_direct_draw_libgtk_only (dc_info->data);
+}
+
 gboolean
 xp_theme_draw (GdkWindow *win, XpThemeElement element, GtkStyle *style,
 	       int x, int y, int width, int height,
@@ -856,9 +897,8 @@ xp_theme_draw (GdkWindow *win, XpThemeElement element, GtkStyle *style,
 {
   HTHEME theme;
   RECT rect, clip, *pClip;
-  int xoff, yoff;
   HDC dc;
-  GdkDrawable *drawable;
+  XpDCInfo dc_info;
   int part_state;
 
   if (!xp_theme_is_drawable (element))
@@ -871,26 +911,16 @@ xp_theme_draw (GdkWindow *win, XpThemeElement element, GtkStyle *style,
   /* FIXME: Recheck its function */
   enable_theme_dialog_texture_func (GDK_WINDOW_HWND (win), ETDT_ENABLETAB);
 
-  if (!GDK_IS_WINDOW (win))
-    {
-      xoff = 0;
-      yoff = 0;
-      drawable = win;
-    }
-  else
-    {
-      gdk_window_get_internal_paint_info (win, &drawable, &xoff, &yoff);
-    }
-
-  rect.left = x - xoff;
-  rect.top = y - yoff;
-  rect.right = rect.left + width;
-  rect.bottom = rect.top + height;
+  dc = get_window_dc (style, win, state_type, &dc_info,
+		      x, y, width, height,
+		      &rect);
+  if (!dc)
+    return FALSE;
 
   if (area)
     {
-      clip.left = area->x - xoff;
-      clip.top = area->y - yoff;
+      clip.left = area->x - dc_info.x_offset;
+      clip.top = area->y - dc_info.y_offset;
       clip.right = clip.left + area->width;
       clip.bottom = clip.top + area->height;
 
@@ -901,27 +931,19 @@ xp_theme_draw (GdkWindow *win, XpThemeElement element, GtkStyle *style,
       pClip = NULL;
     }
 
-  gdk_gc_set_clip_rectangle (style->dark_gc[state_type], NULL);
-  dc = gdk_win32_hdc_get (drawable, style->dark_gc[state_type], 0);
-  if (!dc)
-    return FALSE;
-
   part_state = xp_theme_map_gtk_state (element, state_type);
 
   draw_theme_background_func (theme, dc, element_part_map[element],
 			      part_state, &rect, pClip);
 
-  gdk_win32_hdc_release (drawable, style->dark_gc[state_type], 0);
-
+  release_window_dc (&dc_info);
+  
   return TRUE;
 }
 
 gboolean
 xp_theme_is_active (void)
 {
-  /* Workaround for bug #598299 */
-  return FALSE;
-
   return use_xp_theme;
 }
 
diff --git a/modules/engines/ms-windows/xp_theme.h b/modules/engines/ms-windows/xp_theme.h
index 54d5de0..2d172f3 100755
--- a/modules/engines/ms-windows/xp_theme.h
+++ b/modules/engines/ms-windows/xp_theme.h
@@ -113,6 +113,26 @@ typedef enum
   XP_THEME_FONT_MESSAGE
 } XpThemeFont;
 
+typedef struct
+{
+  GdkDrawable *drawable;
+  GdkGC *gc;
+  
+  gint x_offset;
+  gint y_offset;
+  
+  /*< private >*/
+  gpointer data;
+} XpDCInfo;
+
+HDC get_window_dc (GtkStyle *style,
+		   GdkWindow *window,
+		   GtkStateType state_type,
+		   XpDCInfo *dc_info_out,
+		   gint x, gint y, gint width, gint height,
+		   RECT *rect_out);
+void release_window_dc (XpDCInfo *dc_info);
+
 void xp_theme_init (void);
 void xp_theme_reset (void);
 void xp_theme_exit (void);



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