[PATCH 1/7] uxtheme: Partial implementation of BeginBufferedPaint()
Nikolay Sivov
nsivov at codeweavers.com
Wed Feb 8 16:42:34 CST 2017
Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
---
dlls/uxtheme/buffer.c | 92 +++++++++++++++++++++++++++++++++++++--------
dlls/uxtheme/tests/system.c | 40 ++++++++++++++++----
2 files changed, 109 insertions(+), 23 deletions(-)
diff --git a/dlls/uxtheme/buffer.c b/dlls/uxtheme/buffer.c
index 8583f1a704..972df685f7 100644
--- a/dlls/uxtheme/buffer.c
+++ b/dlls/uxtheme/buffer.c
@@ -2,6 +2,7 @@
* uxtheme Double-buffered Drawing API
*
* Copyright (C) 2008 Reece H. Dunn
+ * Copyright 2017 Nikolay Sivov for CodeWeavers
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -34,6 +35,20 @@
WINE_DEFAULT_DEBUG_CHANNEL(uxtheme);
+struct paintbuffer
+{
+ HDC targetdc;
+ HDC memorydc;
+ RECT rect;
+ void *bits;
+};
+
+static void free_paintbuffer(struct paintbuffer *buffer)
+{
+ DeleteDC(buffer->memorydc);
+ HeapFree(GetProcessHeap(), 0, buffer);
+}
+
/***********************************************************************
* BufferedPaintInit (UXTHEME.@)
*/
@@ -55,24 +70,71 @@ HRESULT WINAPI BufferedPaintUnInit(VOID)
/***********************************************************************
* BeginBufferedPaint (UXTHEME.@)
*/
-HPAINTBUFFER WINAPI BeginBufferedPaint(HDC hdcTarget,
- const RECT * prcTarget,
- BP_BUFFERFORMAT dwFormat,
- BP_PAINTPARAMS *pPaintParams,
- HDC *phdc)
+HPAINTBUFFER WINAPI BeginBufferedPaint(HDC targetdc, const RECT *rect,
+ BP_BUFFERFORMAT format, BP_PAINTPARAMS *params, HDC *retdc)
{
- static int i;
-
- TRACE("Stub (%p %p %d %p %p)\n", hdcTarget, prcTarget, dwFormat,
- pPaintParams, phdc);
-
- if (!i++)
- FIXME("Stub (%p %p %d %p %p)\n", hdcTarget, prcTarget, dwFormat,
- pPaintParams, phdc);
- return NULL;
+ char bmibuf[FIELD_OFFSET(BITMAPINFO, bmiColors[256])];
+ BITMAPINFO *bmi = (BITMAPINFO *)bmibuf;
+ struct paintbuffer *buffer;
+ HBITMAP hbm;
+
+ TRACE("(%p %s %d %p %p)\n", targetdc, wine_dbgstr_rect(rect), format,
+ params, retdc);
+
+ if (retdc)
+ *retdc = NULL;
+
+ if (!targetdc || IsRectEmpty(rect))
+ return NULL;
+
+ if (params)
+ FIXME("painting parameters are ignored\n");
+
+ buffer = HeapAlloc(GetProcessHeap(), 0, sizeof(*buffer));
+ buffer->targetdc = targetdc;
+ buffer->rect = *rect;
+ buffer->memorydc = CreateCompatibleDC(targetdc);
+
+ switch (format)
+ {
+ case BPBF_COMPATIBLEBITMAP:
+ hbm = CreateCompatibleBitmap(buffer->memorydc, rect->right - rect->left, rect->bottom - rect->top);
+ buffer->bits = NULL;
+ break;
+ case BPBF_DIB:
+ case BPBF_TOPDOWNDIB:
+ case BPBF_TOPDOWNMONODIB:
+ /* create DIB section */
+ memset(bmi, 0, sizeof(bmibuf));
+ bmi->bmiHeader.biSize = sizeof(bmi->bmiHeader);
+ bmi->bmiHeader.biHeight = format == BPBF_DIB ? rect->bottom - rect->top :
+ -(rect->bottom - rect->top);
+ bmi->bmiHeader.biWidth = rect->right - rect->left;
+ bmi->bmiHeader.biBitCount = format == BPBF_TOPDOWNMONODIB ? 1 : 32;
+ bmi->bmiHeader.biPlanes = 1;
+ bmi->bmiHeader.biCompression = BI_RGB;
+ hbm = CreateDIBSection(buffer->memorydc, bmi, DIB_RGB_COLORS, &buffer->bits, NULL, 0);
+ break;
+ default:
+ WARN("Unknown buffer format %d\n", format);
+ free_paintbuffer(buffer);
+ return NULL;
+ }
+
+ if (!hbm)
+ {
+ WARN("Failed to create buffer bitmap\n");
+ free_paintbuffer(buffer);
+ return NULL;
+ }
+
+ DeleteObject(SelectObject(buffer->memorydc, hbm));
+
+ *retdc = buffer->memorydc;
+
+ return (HPAINTBUFFER)buffer;
}
-
/***********************************************************************
* EndBufferedPaint (UXTHEME.@)
*/
diff --git a/dlls/uxtheme/tests/system.c b/dlls/uxtheme/tests/system.c
index d7ba43c6d6..66f696b62e 100644
--- a/dlls/uxtheme/tests/system.c
+++ b/dlls/uxtheme/tests/system.c
@@ -552,31 +552,55 @@ static void test_buffered_paint(void)
¶ms, NULL);
ok(buffer == NULL, "Unexpected buffer %p\n", buffer);
+ src = (void *)0xdeadbeef;
buffer = pBeginBufferedPaint(target, NULL, BPBF_COMPATIBLEBITMAP,
¶ms, &src);
ok(buffer == NULL, "Unexpected buffer %p\n", buffer);
+ ok(src == NULL, "Unexpected buffered dc %p\n", src);
/* target rect is mandatory */
- rect.left = rect.top = 0;
- rect.right = rect.bottom = 0;
+ SetRectEmpty(&rect);
+ src = (void *)0xdeadbeef;
buffer = pBeginBufferedPaint(target, &rect, BPBF_COMPATIBLEBITMAP,
¶ms, &src);
ok(buffer == NULL, "Unexpected buffer %p\n", buffer);
+ ok(src == NULL, "Unexpected buffered dc %p\n", src);
- rect.left = rect.top = 0;
- rect.right = rect.bottom = 5;
+ /* inverted rectangle */
+ SetRect(&rect, 10, 0, 5, 5);
+ src = (void *)0xdeadbeef;
+ buffer = pBeginBufferedPaint(target, &rect, BPBF_COMPATIBLEBITMAP,
+ ¶ms, &src);
+ ok(buffer == NULL, "Unexpected buffer %p\n", buffer);
+ ok(src == NULL, "Unexpected buffered dc %p\n", src);
+
+ SetRect(&rect, 0, 10, 5, 0);
+ src = (void *)0xdeadbeef;
+ buffer = pBeginBufferedPaint(target, &rect, BPBF_COMPATIBLEBITMAP,
+ ¶ms, &src);
+ ok(buffer == NULL, "Unexpected buffer %p\n", buffer);
+ ok(src == NULL, "Unexpected buffered dc %p\n", src);
+
+ /* valid rectangle, no target dc */
+ SetRect(&rect, 0, 0, 5, 5);
+ src = (void *)0xdeadbeef;
+ buffer = pBeginBufferedPaint(NULL, &rect, BPBF_COMPATIBLEBITMAP,
+ ¶ms, &src);
+ ok(buffer == NULL, "Unexpected buffer %p\n", buffer);
+ ok(src == NULL, "Unexpected buffered dc %p\n", src);
+
+ SetRect(&rect, 0, 0, 5, 5);
+ src = NULL;
buffer = pBeginBufferedPaint(target, &rect, BPBF_COMPATIBLEBITMAP,
¶ms, &src);
-todo_wine
ok(buffer != NULL, "Unexpected buffer %p\n", buffer);
+ ok(src != NULL, "Expected buffered dc\n");
hr = pEndBufferedPaint(buffer, FALSE);
ok(hr == S_OK, "Unexpected return code %#x\n", hr);
- rect.left = rect.top = 0;
- rect.right = rect.bottom = 5;
+ SetRect(&rect, 0, 0, 5, 5);
buffer = pBeginBufferedPaint(target, &rect, BPBF_COMPATIBLEBITMAP,
¶ms, &src);
-todo_wine
ok(buffer != NULL, "Unexpected buffer %p\n", buffer);
/* clearing */
--
2.11.0
More information about the wine-patches
mailing list