Module: wine Branch: master Commit: 35ae7c8f5939c0ba77b4023a14596706852f5acd URL: http://source.winehq.org/git/wine.git/?a=commit;h=35ae7c8f5939c0ba77b4023a14...
Author: Nikolay Sivov nsivov@codeweavers.com Date: Thu Feb 9 01:42:34 2017 +0300
uxtheme: Partial implementation of BeginBufferedPaint().
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com Signed-off-by: Alexandre Julliard julliard@winehq.org
---
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 8583f1a..972df68 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 d7ba43c..66f696b 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 */