| /* |
| * 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 |
| * License as published by the Free Software Foundation; either |
| * version 2.1 of the License, or (at your option) any later version. |
| * |
| * This library is distributed in the hope that it will be useful, |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| * Lesser General Public License for more details. |
| * |
| * You should have received a copy of the GNU Lesser General Public |
| * License along with this library; if not, write to the Free Software |
| * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA |
| */ |
| |
| #include "config.h" |
| |
| #include <stdlib.h> |
| #include <stdarg.h> |
| |
| #include "windef.h" |
| #include "winbase.h" |
| #include "winuser.h" |
| #include "wingdi.h" |
| #include "vfwmsgs.h" |
| #include "uxtheme.h" |
| |
| #include "wine/debug.h" |
| |
| WINE_DEFAULT_DEBUG_CHANNEL(uxtheme); |
| |
| struct paintbuffer |
| { |
| HDC targetdc; |
| HDC memorydc; |
| HBITMAP bitmap; |
| RECT rect; |
| void *bits; |
| }; |
| |
| static void free_paintbuffer(struct paintbuffer *buffer) |
| { |
| DeleteObject(buffer->bitmap); |
| DeleteDC(buffer->memorydc); |
| HeapFree(GetProcessHeap(), 0, buffer); |
| } |
| |
| static struct paintbuffer *get_buffer_obj(HPAINTBUFFER handle) |
| { |
| if (!handle) |
| return NULL; |
| return handle; |
| } |
| |
| /*********************************************************************** |
| * BufferedPaintInit (UXTHEME.@) |
| */ |
| HRESULT WINAPI BufferedPaintInit(VOID) |
| { |
| FIXME("Stub ()\n"); |
| return S_OK; |
| } |
| |
| /*********************************************************************** |
| * BufferedPaintUnInit (UXTHEME.@) |
| */ |
| HRESULT WINAPI BufferedPaintUnInit(VOID) |
| { |
| FIXME("Stub ()\n"); |
| return S_OK; |
| } |
| |
| /*********************************************************************** |
| * BeginBufferedPaint (UXTHEME.@) |
| */ |
| HPAINTBUFFER WINAPI BeginBufferedPaint(HDC targetdc, const RECT *rect, |
| BP_BUFFERFORMAT format, BP_PAINTPARAMS *params, HDC *retdc) |
| { |
| char bmibuf[FIELD_OFFSET(BITMAPINFO, bmiColors[256])]; |
| BITMAPINFO *bmi = (BITMAPINFO *)bmibuf; |
| struct paintbuffer *buffer; |
| |
| 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: |
| buffer->bitmap = CreateCompatibleBitmap(targetdc, 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; |
| buffer->bitmap = CreateDIBSection(buffer->memorydc, bmi, DIB_RGB_COLORS, &buffer->bits, NULL, 0); |
| break; |
| default: |
| WARN("Unknown buffer format %d\n", format); |
| buffer->bitmap = NULL; |
| free_paintbuffer(buffer); |
| return NULL; |
| } |
| |
| if (!buffer->bitmap) |
| { |
| WARN("Failed to create buffer bitmap\n"); |
| free_paintbuffer(buffer); |
| return NULL; |
| } |
| |
| SetWindowOrgEx(buffer->memorydc, rect->left, rect->top, NULL); |
| IntersectClipRect(buffer->memorydc, rect->left, rect->top, rect->right, rect->bottom); |
| DeleteObject(SelectObject(buffer->memorydc, buffer->bitmap)); |
| |
| *retdc = buffer->memorydc; |
| |
| return (HPAINTBUFFER)buffer; |
| } |
| |
| /*********************************************************************** |
| * EndBufferedPaint (UXTHEME.@) |
| */ |
| HRESULT WINAPI EndBufferedPaint(HPAINTBUFFER bufferhandle, BOOL update) |
| { |
| struct paintbuffer *buffer = get_buffer_obj(bufferhandle); |
| |
| TRACE("(%p %d)\n", bufferhandle, update); |
| |
| if (!buffer) |
| return E_INVALIDARG; |
| |
| if (update) |
| { |
| if (!BitBlt(buffer->targetdc, buffer->rect.left, buffer->rect.top, |
| buffer->rect.right - buffer->rect.left, buffer->rect.bottom - buffer->rect.top, |
| buffer->memorydc, buffer->rect.left, buffer->rect.top, SRCCOPY)) |
| { |
| WARN("BitBlt() failed\n"); |
| } |
| } |
| |
| free_paintbuffer(buffer); |
| return S_OK; |
| } |
| |
| /*********************************************************************** |
| * BufferedPaintClear (UXTHEME.@) |
| */ |
| HRESULT WINAPI BufferedPaintClear(HPAINTBUFFER hBufferedPaint, const RECT *prc) |
| { |
| FIXME("Stub (%p %p)\n", hBufferedPaint, prc); |
| return E_NOTIMPL; |
| } |
| |
| /*********************************************************************** |
| * BufferedPaintSetAlpha (UXTHEME.@) |
| */ |
| HRESULT WINAPI BufferedPaintSetAlpha(HPAINTBUFFER hBufferedPaint, const RECT *prc, BYTE alpha) |
| { |
| FIXME("Stub (%p %p %u)\n", hBufferedPaint, prc, alpha); |
| return E_NOTIMPL; |
| } |
| |
| /*********************************************************************** |
| * GetBufferedPaintBits (UXTHEME.@) |
| */ |
| HRESULT WINAPI GetBufferedPaintBits(HPAINTBUFFER bufferhandle, RGBQUAD **bits, int *width) |
| { |
| struct paintbuffer *buffer = get_buffer_obj(bufferhandle); |
| |
| TRACE("(%p %p %p)\n", buffer, bits, width); |
| |
| if (!bits || !width) |
| return E_POINTER; |
| |
| if (!buffer || !buffer->bits) |
| return E_FAIL; |
| |
| *bits = buffer->bits; |
| *width = buffer->rect.right - buffer->rect.left; |
| |
| return S_OK; |
| } |
| |
| /*********************************************************************** |
| * GetBufferedPaintDC (UXTHEME.@) |
| */ |
| HDC WINAPI GetBufferedPaintDC(HPAINTBUFFER bufferhandle) |
| { |
| struct paintbuffer *buffer = get_buffer_obj(bufferhandle); |
| |
| TRACE("(%p)\n", buffer); |
| |
| return buffer ? buffer->memorydc : NULL; |
| } |
| |
| /*********************************************************************** |
| * GetBufferedPaintTargetDC (UXTHEME.@) |
| */ |
| HDC WINAPI GetBufferedPaintTargetDC(HPAINTBUFFER bufferhandle) |
| { |
| struct paintbuffer *buffer = get_buffer_obj(bufferhandle); |
| |
| TRACE("(%p)\n", buffer); |
| |
| return buffer ? buffer->targetdc : NULL; |
| } |
| |
| /*********************************************************************** |
| * GetBufferedPaintTargetRect (UXTHEME.@) |
| */ |
| HRESULT WINAPI GetBufferedPaintTargetRect(HPAINTBUFFER bufferhandle, RECT *rect) |
| { |
| struct paintbuffer *buffer = get_buffer_obj(bufferhandle); |
| |
| TRACE("(%p %p)\n", buffer, rect); |
| |
| if (!rect) |
| return E_POINTER; |
| |
| if (!buffer) |
| return E_FAIL; |
| |
| *rect = buffer->rect; |
| return S_OK; |
| } |
| |
| /*********************************************************************** |
| * BeginBufferedAnimation (UXTHEME.@) |
| */ |
| HANIMATIONBUFFER WINAPI BeginBufferedAnimation(HWND hwnd, HDC hdcTarget, const RECT *rcTarget, |
| BP_BUFFERFORMAT dwFormat, BP_PAINTPARAMS *pPaintParams, |
| BP_ANIMATIONPARAMS *pAnimationParams, HDC *phdcFrom, |
| HDC *phdcTo) |
| { |
| FIXME("Stub (%p %p %p %u %p %p %p %p)\n", hwnd, hdcTarget, rcTarget, dwFormat, |
| pPaintParams, pAnimationParams, phdcFrom, phdcTo); |
| |
| return NULL; |
| } |
| |
| /*********************************************************************** |
| * BufferedPaintRenderAnimation (UXTHEME.@) |
| */ |
| BOOL WINAPI BufferedPaintRenderAnimation(HWND hwnd, HDC hdcTarget) |
| { |
| FIXME("Stub (%p %p)\n", hwnd, hdcTarget); |
| |
| return FALSE; |
| } |
| |
| /*********************************************************************** |
| * BufferedPaintStopAllAnimations (UXTHEME.@) |
| */ |
| HRESULT WINAPI BufferedPaintStopAllAnimations(HWND hwnd) |
| { |
| FIXME("Stub (%p)\n", hwnd); |
| |
| return E_NOTIMPL; |
| } |
| |
| /*********************************************************************** |
| * EndBufferedAnimation (UXTHEME.@) |
| */ |
| HRESULT WINAPI EndBufferedAnimation(HANIMATIONBUFFER hbpAnimation, BOOL fUpdateTarget) |
| { |
| FIXME("Stub (%p %u)\n", hbpAnimation, fUpdateTarget); |
| |
| return E_NOTIMPL; |
| } |