324 lines
10 KiB
C
324 lines
10 KiB
C
/* DirectDrawClipper implementation
|
|
*
|
|
* Copyright 2000 (c) Marcus Meissner
|
|
* Copyright 2000 (c) TransGaming Technologies Inc.
|
|
* Copyright 2006 (c) Stefan Dösinger
|
|
*
|
|
* 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 "wine/port.h"
|
|
|
|
#include "ddraw_private.h"
|
|
|
|
WINE_DEFAULT_DEBUG_CHANNEL(ddraw);
|
|
|
|
static inline IDirectDrawClipperImpl *impl_from_IDirectDrawClipper(IDirectDrawClipper *iface)
|
|
{
|
|
return CONTAINING_RECORD(iface, IDirectDrawClipperImpl, IDirectDrawClipper_iface);
|
|
}
|
|
|
|
/*****************************************************************************
|
|
* IDirectDrawClipper::QueryInterface
|
|
*
|
|
* Can query the IUnknown and IDirectDrawClipper interface from a
|
|
* Clipper object. The IUnknown Interface is equal to the IDirectDrawClipper
|
|
* interface. Can't create other interfaces.
|
|
*
|
|
* Arguments:
|
|
* riid: Interface id asked for
|
|
* ppvObj: Returns the pointer to the interface
|
|
*
|
|
* Return values:
|
|
* DD_OK on success
|
|
* E_NOINTERFACE if the requested interface wasn't found.
|
|
*
|
|
*****************************************************************************/
|
|
static HRESULT WINAPI IDirectDrawClipperImpl_QueryInterface(IDirectDrawClipper *iface, REFIID riid,
|
|
void **ppvObj)
|
|
{
|
|
|
|
TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), ppvObj);
|
|
|
|
if (IsEqualGUID(&IID_IDirectDrawClipper, riid)
|
|
|| IsEqualGUID(&IID_IUnknown, riid))
|
|
{
|
|
IUnknown_AddRef(iface);
|
|
*ppvObj = iface;
|
|
return S_OK;
|
|
}
|
|
|
|
return E_NOINTERFACE;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
* IDirectDrawClipper::AddRef
|
|
*
|
|
* Increases the reference count of the interface, returns the new count
|
|
*
|
|
*****************************************************************************/
|
|
static ULONG WINAPI IDirectDrawClipperImpl_AddRef(IDirectDrawClipper *iface)
|
|
{
|
|
IDirectDrawClipperImpl *This = impl_from_IDirectDrawClipper(iface);
|
|
ULONG ref = InterlockedIncrement(&This->ref);
|
|
|
|
TRACE("%p increasing refcount to %u.\n", This, ref);
|
|
|
|
return ref;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
* IDirectDrawClipper::Release
|
|
*
|
|
* Decreases the reference count of the interface, returns the new count
|
|
* If the refcount is decreased to 0, the interface is destroyed.
|
|
*
|
|
*****************************************************************************/
|
|
static ULONG WINAPI IDirectDrawClipperImpl_Release(IDirectDrawClipper *iface)
|
|
{
|
|
IDirectDrawClipperImpl *This = impl_from_IDirectDrawClipper(iface);
|
|
ULONG ref = InterlockedDecrement(&This->ref);
|
|
|
|
TRACE("%p decreasing refcount to %u.\n", This, ref);
|
|
|
|
if (ref == 0)
|
|
{
|
|
wined3d_mutex_lock();
|
|
wined3d_clipper_decref(This->wineD3DClipper);
|
|
wined3d_mutex_unlock();
|
|
HeapFree(GetProcessHeap(), 0, This);
|
|
return 0;
|
|
}
|
|
else return ref;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
* IDirectDrawClipper::SetHWnd
|
|
*
|
|
* Assigns a hWnd to the clipper interface.
|
|
*
|
|
* Arguments:
|
|
* Flags: Unsupported so far
|
|
* hWnd: The hWnd to set
|
|
*
|
|
* Return values:
|
|
* DD_OK on success
|
|
* DDERR_INVALIDPARAMS if Flags was != 0
|
|
*
|
|
*****************************************************************************/
|
|
|
|
static HRESULT WINAPI IDirectDrawClipperImpl_SetHWnd(IDirectDrawClipper *iface, DWORD dwFlags,
|
|
HWND hWnd)
|
|
{
|
|
IDirectDrawClipperImpl *This = impl_from_IDirectDrawClipper(iface);
|
|
HRESULT hr;
|
|
|
|
TRACE("iface %p, flags %#x, window %p.\n", iface, dwFlags, hWnd);
|
|
|
|
wined3d_mutex_lock();
|
|
hr = wined3d_clipper_set_window(This->wineD3DClipper, dwFlags, hWnd);
|
|
wined3d_mutex_unlock();
|
|
|
|
switch(hr)
|
|
{
|
|
case WINED3DERR_INVALIDCALL: return DDERR_INVALIDPARAMS;
|
|
default: return hr;
|
|
}
|
|
}
|
|
|
|
/*****************************************************************************
|
|
* IDirectDrawClipper::GetClipList
|
|
*
|
|
* Retrieve a copy of the clip list
|
|
*
|
|
* Arguments:
|
|
* Rect: Rectangle to be used to clip the clip list or NULL for the
|
|
* entire clip list
|
|
* ClipList: structure for the resulting copy of the clip list.
|
|
* If NULL, fills Size up to the number of bytes necessary to hold
|
|
* the entire clip.
|
|
* Size: Size of resulting clip list; size of the buffer at ClipList
|
|
* or, if ClipList is NULL, receives the required size of the buffer
|
|
* in bytes
|
|
*
|
|
* RETURNS
|
|
* Either DD_OK or DDERR_*
|
|
************************************************************************/
|
|
static HRESULT WINAPI IDirectDrawClipperImpl_GetClipList(IDirectDrawClipper *iface, RECT *lpRect,
|
|
RGNDATA *lpClipList, DWORD *lpdwSize)
|
|
{
|
|
IDirectDrawClipperImpl *This = impl_from_IDirectDrawClipper(iface);
|
|
HRESULT hr;
|
|
|
|
TRACE("iface %p, rect %s, clip_list %p, clip_list_size %p.\n",
|
|
iface, wine_dbgstr_rect(lpRect), lpClipList, lpdwSize);
|
|
|
|
wined3d_mutex_lock();
|
|
hr = wined3d_clipper_get_clip_list(This->wineD3DClipper, lpRect, lpClipList, lpdwSize);
|
|
wined3d_mutex_unlock();
|
|
|
|
return hr;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
* IDirectDrawClipper::SetClipList
|
|
*
|
|
* Sets or deletes (if lprgn is NULL) the clip list
|
|
*
|
|
* This implementation is a stub and returns DD_OK always to make the app
|
|
* happy.
|
|
*
|
|
* PARAMS
|
|
* lprgn Pointer to a LRGNDATA structure or NULL
|
|
* dwFlags not used, must be 0
|
|
* RETURNS
|
|
* Either DD_OK or DDERR_*
|
|
*****************************************************************************/
|
|
static HRESULT WINAPI IDirectDrawClipperImpl_SetClipList(IDirectDrawClipper *iface, RGNDATA *lprgn,
|
|
DWORD dwFlag)
|
|
{
|
|
IDirectDrawClipperImpl *This = impl_from_IDirectDrawClipper(iface);
|
|
HRESULT hr;
|
|
|
|
TRACE("iface %p, clip_list %p, flags %#x.\n", iface, lprgn, dwFlag);
|
|
|
|
wined3d_mutex_lock();
|
|
hr = wined3d_clipper_set_clip_list(This->wineD3DClipper, lprgn, dwFlag);
|
|
wined3d_mutex_unlock();
|
|
|
|
return hr;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
* IDirectDrawClipper::GetHWnd
|
|
*
|
|
* Returns the hwnd assigned with SetHWnd
|
|
*
|
|
* Arguments:
|
|
* hWndPtr: Address to store the HWND at
|
|
*
|
|
* Return values:
|
|
* Always returns DD_OK;
|
|
*****************************************************************************/
|
|
static HRESULT WINAPI IDirectDrawClipperImpl_GetHWnd(IDirectDrawClipper *iface, HWND *hWndPtr)
|
|
{
|
|
IDirectDrawClipperImpl *This = impl_from_IDirectDrawClipper(iface);
|
|
HRESULT hr;
|
|
|
|
TRACE("iface %p, window %p.\n", iface, hWndPtr);
|
|
|
|
wined3d_mutex_lock();
|
|
hr = wined3d_clipper_get_window(This->wineD3DClipper, hWndPtr);
|
|
wined3d_mutex_unlock();
|
|
|
|
return hr;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
* IDirectDrawClipper::Initialize
|
|
*
|
|
* Initializes the interface. Well, there isn't much to do for this
|
|
* implementation, but it stores the DirectDraw Interface.
|
|
*
|
|
* Arguments:
|
|
* DD: Pointer to a IDirectDraw interface
|
|
* Flags: Unsupported by now
|
|
*
|
|
* Return values:
|
|
* DD_OK on success
|
|
* DDERR_ALREADYINITIALIZED if this interface isn't initialized already
|
|
*****************************************************************************/
|
|
static HRESULT WINAPI IDirectDrawClipperImpl_Initialize(IDirectDrawClipper *iface,
|
|
IDirectDraw *ddraw, DWORD dwFlags)
|
|
{
|
|
IDirectDrawClipperImpl *This = impl_from_IDirectDrawClipper(iface);
|
|
|
|
TRACE("iface %p, ddraw %p, flags %#x.\n", iface, ddraw, dwFlags);
|
|
|
|
wined3d_mutex_lock();
|
|
if (This->initialized)
|
|
{
|
|
wined3d_mutex_unlock();
|
|
return DDERR_ALREADYINITIALIZED;
|
|
}
|
|
|
|
This->initialized = TRUE;
|
|
wined3d_mutex_unlock();
|
|
|
|
return DD_OK;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
* IDirectDrawClipper::IsClipListChanged
|
|
*
|
|
* This function is a stub
|
|
*
|
|
* Arguments:
|
|
* Changed:
|
|
*
|
|
* Return values:
|
|
* DD_OK, because it's a stub
|
|
*****************************************************************************/
|
|
static HRESULT WINAPI IDirectDrawClipperImpl_IsClipListChanged(IDirectDrawClipper *iface,
|
|
BOOL *lpbChanged)
|
|
{
|
|
FIXME("iface %p, changed %p stub!\n", iface, lpbChanged);
|
|
|
|
/* XXX What is safest? */
|
|
*lpbChanged = FALSE;
|
|
|
|
return DD_OK;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
* The VTable
|
|
*****************************************************************************/
|
|
static const struct IDirectDrawClipperVtbl ddraw_clipper_vtbl =
|
|
{
|
|
IDirectDrawClipperImpl_QueryInterface,
|
|
IDirectDrawClipperImpl_AddRef,
|
|
IDirectDrawClipperImpl_Release,
|
|
IDirectDrawClipperImpl_GetClipList,
|
|
IDirectDrawClipperImpl_GetHWnd,
|
|
IDirectDrawClipperImpl_Initialize,
|
|
IDirectDrawClipperImpl_IsClipListChanged,
|
|
IDirectDrawClipperImpl_SetClipList,
|
|
IDirectDrawClipperImpl_SetHWnd
|
|
};
|
|
|
|
HRESULT ddraw_clipper_init(IDirectDrawClipperImpl *clipper)
|
|
{
|
|
clipper->IDirectDrawClipper_iface.lpVtbl = &ddraw_clipper_vtbl;
|
|
clipper->ref = 1;
|
|
clipper->wineD3DClipper = wined3d_clipper_create();
|
|
if (!clipper->wineD3DClipper)
|
|
{
|
|
WARN("Failed to create wined3d clipper.\n");
|
|
return E_OUTOFMEMORY;
|
|
}
|
|
|
|
return DD_OK;
|
|
}
|
|
|
|
IDirectDrawClipperImpl *unsafe_impl_from_IDirectDrawClipper(IDirectDrawClipper *iface)
|
|
{
|
|
if (!iface)
|
|
return NULL;
|
|
assert(iface->lpVtbl == &ddraw_clipper_vtbl);
|
|
|
|
return impl_from_IDirectDrawClipper(iface);
|
|
}
|