From d22d101f9787e492df11d0a48c307a09ea71bf5d Mon Sep 17 00:00:00 2001 From: Cody Russell Date: Mon, 30 Apr 2007 15:30:38 +0000 Subject: Clear correct area svn path=/branches/gtk-2-10/; revision=17738 --- gdk/win32/gdkwindow-win32.c | 151 ++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 147 insertions(+), 4 deletions(-) (limited to 'gdk') diff --git a/gdk/win32/gdkwindow-win32.c b/gdk/win32/gdkwindow-win32.c index 1e8dbaf0b..38cf45aca 100644 --- a/gdk/win32/gdkwindow-win32.c +++ b/gdk/win32/gdkwindow-win32.c @@ -1446,6 +1446,139 @@ gdk_window_reparent (GdkWindow *window, _gdk_window_init_position (GDK_WINDOW (window_private)); } +static void +erase_background (GdkWindow *window, + HDC hdc) +{ + HDC bgdc = NULL; + HBRUSH hbr = NULL; + HPALETTE holdpal = NULL; + RECT rect; + COLORREF bg; + GdkColormap *colormap; + GdkColormapPrivateWin32 *colormap_private; + int x, y; + int x_offset, y_offset; + + if (((GdkWindowObject *) window)->input_only || + ((GdkWindowObject *) window)->bg_pixmap == GDK_NO_BG || + GDK_WINDOW_IMPL_WIN32 (((GdkWindowObject *) window)->impl)->position_info.no_bg) + { + return; + } + + colormap = gdk_drawable_get_colormap (window); + + if (colormap && + (colormap->visual->type == GDK_VISUAL_PSEUDO_COLOR || + colormap->visual->type == GDK_VISUAL_STATIC_COLOR)) + { + int k; + + colormap_private = GDK_WIN32_COLORMAP_DATA (colormap); + + if (!(holdpal = SelectPalette (hdc, colormap_private->hpal, FALSE))) + WIN32_GDI_FAILED ("SelectPalette"); + else if ((k = RealizePalette (hdc)) == GDI_ERROR) + WIN32_GDI_FAILED ("RealizePalette"); + else if (k > 0) + GDK_NOTE (COLORMAP, g_print ("erase_background: realized %p: %d colors\n", + colormap_private->hpal, k)); + } + + x_offset = y_offset = 0; + while (window && ((GdkWindowObject *) window)->bg_pixmap == GDK_PARENT_RELATIVE_BG) + { + /* If this window should have the same background as the parent, + * fetch the parent. (And if the same goes for the parent, fetch + * the grandparent, etc.) + */ + x_offset += ((GdkWindowObject *) window)->x; + y_offset += ((GdkWindowObject *) window)->y; + window = GDK_WINDOW (((GdkWindowObject *) window)->parent); + } + + if (GDK_WINDOW_IMPL_WIN32 (((GdkWindowObject *) window)->impl)->position_info.no_bg) + { + /* Improves scolling effect, e.g. main buttons of testgtk */ + return; + } + + GetClipBox (hdc, &rect); + + if (((GdkWindowObject *) window)->bg_pixmap == NULL) + { + bg = _gdk_win32_colormap_color (GDK_DRAWABLE_IMPL_WIN32 (((GdkWindowObject *) window)->impl)->colormap, + ((GdkWindowObject *) window)->bg_color.pixel); + + if (!(hbr = CreateSolidBrush (bg))) + WIN32_GDI_FAILED ("CreateSolidBrush"); + else if (!FillRect (hdc, &rect, hbr)) + WIN32_GDI_FAILED ("FillRect"); + if (hbr != NULL) + DeleteObject (hbr); + } + else if (((GdkWindowObject *) window)->bg_pixmap != GDK_NO_BG) + { + GdkPixmap *pixmap = ((GdkWindowObject *) window)->bg_pixmap; + GdkPixmapImplWin32 *pixmap_impl = GDK_PIXMAP_IMPL_WIN32 (GDK_PIXMAP_OBJECT (pixmap)->impl); + + if (x_offset == 0 && y_offset == 0 && + pixmap_impl->width <= 8 && pixmap_impl->height <= 8) + { + if (!(hbr = CreatePatternBrush (GDK_PIXMAP_HBITMAP (pixmap)))) + WIN32_GDI_FAILED ("CreatePatternBrush"); + else if (!FillRect (hdc, &rect, hbr)) + WIN32_GDI_FAILED ("FillRect"); + if (hbr != NULL) + DeleteObject (hbr); + } + else + { + HGDIOBJ oldbitmap; + + if (!(bgdc = CreateCompatibleDC (hdc))) + { + WIN32_GDI_FAILED ("CreateCompatibleDC"); + return; + } + if (!(oldbitmap = SelectObject (bgdc, GDK_PIXMAP_HBITMAP (pixmap)))) + { + WIN32_GDI_FAILED ("SelectObject"); + DeleteDC (bgdc); + return; + } + x = -x_offset; + while (x < rect.right) + { + if (x + pixmap_impl->width >= rect.left) + { + y = -y_offset; + while (y < rect.bottom) + { + if (y + pixmap_impl->height >= rect.top) + { + if (!BitBlt (hdc, x, y, + pixmap_impl->width, pixmap_impl->height, + bgdc, 0, 0, SRCCOPY)) + { + WIN32_GDI_FAILED ("BitBlt"); + SelectObject (bgdc, oldbitmap); + DeleteDC (bgdc); + return; + } + } + y += pixmap_impl->height; + } + } + x += pixmap_impl->width; + } + SelectObject (bgdc, oldbitmap); + DeleteDC (bgdc); + } + } +} + void _gdk_windowing_window_clear_area (GdkWindow *window, gint x, @@ -1472,8 +1605,9 @@ _gdk_windowing_window_clear_area (GdkWindow *window, GDK_WINDOW_HWND (window), width, height, x, y)); hdc = GetDC (GDK_WINDOW_HWND (window)); - IntersectClipRect (hdc, x, y, x + width + 1, y + height + 1); - SendMessage (GDK_WINDOW_HWND (window), WM_ERASEBKGND, (WPARAM) hdc, 0); + IntersectClipRect (hdc, x, y, x + width, y + height); + erase_background (window, hdc); + GDI_CALL (ReleaseDC, (GDK_WINDOW_HWND (window), hdc)); } } @@ -1489,6 +1623,7 @@ _gdk_windowing_window_clear_area_e (GdkWindow *window, if (!GDK_WINDOW_DESTROYED (window)) { + HDC hdc; RECT rect; GDK_NOTE (MISC, g_print ("_gdk_windowing_window_clear_area_e: %p: " @@ -1496,10 +1631,18 @@ _gdk_windowing_window_clear_area_e (GdkWindow *window, GDK_WINDOW_HWND (window), width, height, x, y)); + /* The background should be erased before the expose event is + generated */ + hdc = GetDC (GDK_WINDOW_HWND (window)); + IntersectClipRect (hdc, x, y, x + width, y + height); + erase_background (window, hdc); + GDI_CALL (ReleaseDC, (GDK_WINDOW_HWND (window), hdc)); + rect.left = x; - rect.right = x + width + 1; + rect.right = x + width; rect.top = y; - rect.bottom = y + height + 1; + rect.bottom = y + height; + GDI_CALL (InvalidateRect, (GDK_WINDOW_HWND (window), &rect, TRUE)); UpdateWindow (GDK_WINDOW_HWND (window)); } -- cgit v1.2.1