Nikolay Sivov : uxtheme: Partial implementation of BeginBufferedPaint().

Alexandre Julliard julliard at winehq.org
Thu Feb 9 15:54:25 CST 2017


Module: wine
Branch: master
Commit: 35ae7c8f5939c0ba77b4023a14596706852f5acd
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=35ae7c8f5939c0ba77b4023a14596706852f5acd

Author: Nikolay Sivov <nsivov at codeweavers.com>
Date:   Thu Feb  9 01:42:34 2017 +0300

uxtheme: Partial implementation of BeginBufferedPaint().

Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at 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)
             &params, NULL);
     ok(buffer == NULL, "Unexpected buffer %p\n", buffer);
 
+    src = (void *)0xdeadbeef;
     buffer = pBeginBufferedPaint(target, NULL, BPBF_COMPATIBLEBITMAP,
             &params, &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,
             &params, &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,
+            &params, &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,
+            &params, &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,
+            &params, &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,
             &params, &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,
             &params, &src);
-todo_wine
     ok(buffer != NULL, "Unexpected buffer %p\n", buffer);
 
     /* clearing */




More information about the wine-cvs mailing list