summaryrefslogtreecommitdiff
path: root/gdk/win32
diff options
context:
space:
mode:
authorAlexander Larsson <alexl@redhat.com>2011-11-10 16:51:07 +0100
committerAlexander Larsson <alexl@redhat.com>2011-11-10 17:41:13 +0100
commit2f14732b1d48b5c4abf378daa0875881ad507c0f (patch)
tree169e18daa723f11f1e8caf5d637765458e6aad8f /gdk/win32
parent68d28aad97894c5b1fa6875b2cb3a9baa0c8284f (diff)
downloadgtk+-2f14732b1d48b5c4abf378daa0875881ad507c0f.tar.gz
win32: Fix gdk_win32_window_translate
We now do proper handling of existing invalid regions, and we use ScrollDC which allows us to specify the right clip region rather than just the bounding rect.
Diffstat (limited to 'gdk/win32')
-rw-r--r--gdk/win32/gdkwindow-win32.c66
1 files changed, 58 insertions, 8 deletions
diff --git a/gdk/win32/gdkwindow-win32.c b/gdk/win32/gdkwindow-win32.c
index 3c3cf6e6dc..0218620ea2 100644
--- a/gdk/win32/gdkwindow-win32.c
+++ b/gdk/win32/gdkwindow-win32.c
@@ -63,6 +63,8 @@ struct _FullscreenInfo
static void update_style_bits (GdkWindow *window);
static gboolean _gdk_window_get_functions (GdkWindow *window,
GdkWMFunction *functions);
+static HDC _gdk_win32_impl_acquire_dc (GdkWindowImplWin32 *impl);
+static void _gdk_win32_impl_release_dc (GdkWindowImplWin32 *impl);
#define WINDOW_IS_TOPLEVEL(window) \
(GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD && \
@@ -3337,20 +3339,68 @@ _gdk_win32_window_translate (GdkWindow *window,
gint dx,
gint dy)
{
+ GdkWindowImplWin32 *impl = GDK_WINDOW_IMPL_WIN32 (window->impl);
GdkRectangle extents;
RECT rect;
+ HRGN hrgn, area_hrgn;
+ HDC hdc;
+ int ret;
+
+ /* Note: This is the destination area, not the source, and
+ it has been moved by dx, dy from the source area */
+ area_hrgn = cairo_region_to_hrgn (area, 0, 0);
+
+ /* First we copy any outstanding invalid areas in the
+ source area to the new position in the destination area */
+ hrgn = CreateRectRgn (0, 0, 0, 0);
+ ret = GetUpdateRgn (GDK_WINDOW_HWND (window), hrgn, FALSE);
+ if (ret == ERROR)
+ WIN32_API_FAILED ("GetUpdateRgn");
+ else if (ret != NULLREGION)
+ {
+ /* Convert the source invalid region as it would be copied */
+ OffsetRgn (hrgn, dx, dy);
+ /* Keep what intersects the copy destination area */
+ ret = CombineRgn (hrgn, hrgn, area_hrgn, RGN_AND);
+ /* And invalidate it */
+ if (ret == ERROR)
+ WIN32_API_FAILED ("CombineRgn");
+ else if (ret != NULLREGION)
+ API_CALL (InvalidateRgn, (GDK_WINDOW_HWND (window), hrgn, TRUE));
+ }
+
+ /* Then we copy the bits, invalidating whatever is copied from
+ otherwise invisible areas */
+
+ hdc = _gdk_win32_impl_acquire_dc (impl);
+
+ /* Clip hdc to target region */
+ API_CALL (SelectClipRgn, (hdc, area_hrgn));
cairo_region_get_extents (area, &extents);
- rect.left = extents.x - dx;
- rect.top = extents.y - dy;
- rect.right = rect.left + extents.width;
- rect.bottom = rect.top + extents.height;
- API_CALL (ScrollWindowEx, (GDK_WINDOW_HWND (window),
- dx, dy, &rect,
- NULL, NULL, NULL,
- SW_INVALIDATE));
+ rect.left = MIN (extents.x, extents.x - dx);
+ rect.top = MIN (extents.y, extents.y - dy);
+ rect.right = MAX (extents.x + extents.width, extents.x - dx + extents.width);
+ rect.bottom = MAX (extents.y + extents.height, extents.y - dy + extents.height);
+
+ SetRectRgn (hrgn, 0, 0, 0, 0);
+
+ if (!ScrollDC (hdc, dx, dy, &rect, NULL, hrgn, NULL))
+ WIN32_GDI_FAILED ("ScrollDC");
+ else if (!InvalidateRgn (GDK_WINDOW_HWND (window), hrgn, FALSE))
+ WIN32_GDI_FAILED ("InvalidateRgn");
+
+ /* Unset hdc clip region */
+ API_CALL (SelectClipRgn, (hdc, NULL));
+
+ _gdk_win32_impl_release_dc (impl);
+
+ if (!DeleteObject (hrgn))
+ WIN32_GDI_FAILED ("DeleteObject");
+ if (!DeleteObject (area_hrgn))
+ WIN32_GDI_FAILED ("DeleteObject");
}
static void