2008-11-10 10:35:59 +01:00
|
|
|
/*
|
|
|
|
* uxtheme Double-buffered Drawing API
|
|
|
|
*
|
|
|
|
* Copyright (C) 2008 Reece H. Dunn
|
2017-02-08 23:42:34 +01:00
|
|
|
* Copyright 2017 Nikolay Sivov for CodeWeavers
|
2008-11-10 10:35:59 +01:00
|
|
|
*
|
|
|
|
* 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"
|
2018-02-25 17:35:15 +01:00
|
|
|
#include "wine/heap.h"
|
2008-11-10 10:35:59 +01:00
|
|
|
|
|
|
|
WINE_DEFAULT_DEBUG_CHANNEL(uxtheme);
|
|
|
|
|
2017-02-08 23:42:34 +01:00
|
|
|
struct paintbuffer
|
|
|
|
{
|
|
|
|
HDC targetdc;
|
|
|
|
HDC memorydc;
|
2017-04-21 22:09:16 +02:00
|
|
|
HBITMAP bitmap;
|
2017-02-08 23:42:34 +01:00
|
|
|
RECT rect;
|
|
|
|
void *bits;
|
|
|
|
};
|
|
|
|
|
|
|
|
static void free_paintbuffer(struct paintbuffer *buffer)
|
|
|
|
{
|
2017-04-21 22:09:16 +02:00
|
|
|
DeleteObject(buffer->bitmap);
|
2017-02-08 23:42:34 +01:00
|
|
|
DeleteDC(buffer->memorydc);
|
2018-02-25 17:35:15 +01:00
|
|
|
heap_free(buffer);
|
2017-02-08 23:42:34 +01:00
|
|
|
}
|
|
|
|
|
2017-02-08 23:42:35 +01:00
|
|
|
static struct paintbuffer *get_buffer_obj(HPAINTBUFFER handle)
|
|
|
|
{
|
|
|
|
if (!handle)
|
|
|
|
return NULL;
|
|
|
|
return handle;
|
|
|
|
}
|
|
|
|
|
2008-11-10 10:35:59 +01:00
|
|
|
/***********************************************************************
|
|
|
|
* 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.@)
|
|
|
|
*/
|
2017-02-08 23:42:34 +01:00
|
|
|
HPAINTBUFFER WINAPI BeginBufferedPaint(HDC targetdc, const RECT *rect,
|
|
|
|
BP_BUFFERFORMAT format, BP_PAINTPARAMS *params, HDC *retdc)
|
2008-11-10 10:35:59 +01:00
|
|
|
{
|
2017-02-08 23:42:34 +01:00
|
|
|
char bmibuf[FIELD_OFFSET(BITMAPINFO, bmiColors[256])];
|
|
|
|
BITMAPINFO *bmi = (BITMAPINFO *)bmibuf;
|
|
|
|
struct paintbuffer *buffer;
|
2010-06-22 21:41:23 +02:00
|
|
|
|
2017-02-08 23:42:34 +01:00
|
|
|
TRACE("(%p %s %d %p %p)\n", targetdc, wine_dbgstr_rect(rect), format,
|
|
|
|
params, retdc);
|
2010-06-22 21:41:23 +02:00
|
|
|
|
2017-02-08 23:42:34 +01:00
|
|
|
if (retdc)
|
|
|
|
*retdc = NULL;
|
|
|
|
|
|
|
|
if (!targetdc || IsRectEmpty(rect))
|
|
|
|
return NULL;
|
2008-11-10 10:35:59 +01:00
|
|
|
|
2017-02-08 23:42:34 +01:00
|
|
|
if (params)
|
|
|
|
FIXME("painting parameters are ignored\n");
|
|
|
|
|
2018-02-25 17:35:15 +01:00
|
|
|
buffer = heap_alloc(sizeof(*buffer));
|
2017-02-08 23:42:34 +01:00
|
|
|
buffer->targetdc = targetdc;
|
|
|
|
buffer->rect = *rect;
|
|
|
|
buffer->memorydc = CreateCompatibleDC(targetdc);
|
|
|
|
|
|
|
|
switch (format)
|
|
|
|
{
|
|
|
|
case BPBF_COMPATIBLEBITMAP:
|
2017-04-21 22:09:16 +02:00
|
|
|
buffer->bitmap = CreateCompatibleBitmap(targetdc, rect->right - rect->left, rect->bottom - rect->top);
|
2017-02-08 23:42:34 +01:00
|
|
|
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;
|
2017-04-21 22:09:16 +02:00
|
|
|
buffer->bitmap = CreateDIBSection(buffer->memorydc, bmi, DIB_RGB_COLORS, &buffer->bits, NULL, 0);
|
2017-02-08 23:42:34 +01:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
WARN("Unknown buffer format %d\n", format);
|
2017-04-21 22:09:16 +02:00
|
|
|
buffer->bitmap = NULL;
|
2017-02-08 23:42:34 +01:00
|
|
|
free_paintbuffer(buffer);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2017-04-21 22:09:16 +02:00
|
|
|
if (!buffer->bitmap)
|
2017-02-08 23:42:34 +01:00
|
|
|
{
|
|
|
|
WARN("Failed to create buffer bitmap\n");
|
|
|
|
free_paintbuffer(buffer);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2017-04-25 07:54:07 +02:00
|
|
|
SetWindowOrgEx(buffer->memorydc, rect->left, rect->top, NULL);
|
|
|
|
IntersectClipRect(buffer->memorydc, rect->left, rect->top, rect->right, rect->bottom);
|
2017-04-21 22:09:16 +02:00
|
|
|
DeleteObject(SelectObject(buffer->memorydc, buffer->bitmap));
|
2017-02-08 23:42:34 +01:00
|
|
|
|
|
|
|
*retdc = buffer->memorydc;
|
|
|
|
|
|
|
|
return (HPAINTBUFFER)buffer;
|
|
|
|
}
|
2008-11-10 10:35:59 +01:00
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* EndBufferedPaint (UXTHEME.@)
|
|
|
|
*/
|
2017-02-08 23:42:35 +01:00
|
|
|
HRESULT WINAPI EndBufferedPaint(HPAINTBUFFER bufferhandle, BOOL update)
|
2008-11-10 10:35:59 +01:00
|
|
|
{
|
2017-02-08 23:42:35 +01:00
|
|
|
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,
|
2017-04-25 07:54:07 +02:00
|
|
|
buffer->memorydc, buffer->rect.left, buffer->rect.top, SRCCOPY))
|
2017-02-08 23:42:35 +01:00
|
|
|
{
|
|
|
|
WARN("BitBlt() failed\n");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
free_paintbuffer(buffer);
|
2008-11-10 10:35:59 +01:00
|
|
|
return S_OK;
|
|
|
|
}
|
2015-04-27 22:52:53 +02:00
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* 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.@)
|
|
|
|
*/
|
2017-02-08 23:42:39 +01:00
|
|
|
HRESULT WINAPI GetBufferedPaintBits(HPAINTBUFFER bufferhandle, RGBQUAD **bits, int *width)
|
2015-04-27 22:52:53 +02:00
|
|
|
{
|
2017-02-08 23:42:39 +01:00
|
|
|
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;
|
2015-04-27 22:52:53 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* GetBufferedPaintDC (UXTHEME.@)
|
|
|
|
*/
|
2017-02-08 23:42:36 +01:00
|
|
|
HDC WINAPI GetBufferedPaintDC(HPAINTBUFFER bufferhandle)
|
2015-04-27 22:52:53 +02:00
|
|
|
{
|
2017-02-08 23:42:36 +01:00
|
|
|
struct paintbuffer *buffer = get_buffer_obj(bufferhandle);
|
|
|
|
|
|
|
|
TRACE("(%p)\n", buffer);
|
|
|
|
|
|
|
|
return buffer ? buffer->memorydc : NULL;
|
2015-04-27 22:52:53 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* GetBufferedPaintTargetDC (UXTHEME.@)
|
|
|
|
*/
|
2017-02-08 23:42:37 +01:00
|
|
|
HDC WINAPI GetBufferedPaintTargetDC(HPAINTBUFFER bufferhandle)
|
2015-04-27 22:52:53 +02:00
|
|
|
{
|
2017-02-08 23:42:37 +01:00
|
|
|
struct paintbuffer *buffer = get_buffer_obj(bufferhandle);
|
|
|
|
|
|
|
|
TRACE("(%p)\n", buffer);
|
|
|
|
|
|
|
|
return buffer ? buffer->targetdc : NULL;
|
2015-04-27 22:52:53 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* GetBufferedPaintTargetRect (UXTHEME.@)
|
|
|
|
*/
|
2017-02-08 23:42:38 +01:00
|
|
|
HRESULT WINAPI GetBufferedPaintTargetRect(HPAINTBUFFER bufferhandle, RECT *rect)
|
2015-04-27 22:52:53 +02:00
|
|
|
{
|
2017-02-08 23:42:38 +01:00
|
|
|
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;
|
2015-04-27 22:52:53 +02:00
|
|
|
}
|
2015-05-12 00:36:41 +02:00
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* 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;
|
|
|
|
}
|