surface.c 44.4 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
/*
 * Copyright 2008 Stefan Dösinger 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 "wine/debug.h"

#define COBJMACROS

#include "winbase.h"
#include "wingdi.h"

#include "ddraw.h"
#include "d3d.h"

#include "ddrawex_private.h"

WINE_DEFAULT_DEBUG_CHANNEL(ddrawex);

/******************************************************************************
 * Helper functions for COM management
 ******************************************************************************/
36
static IDirectDrawSurfaceImpl *impl_from_IDirectDrawSurface3(IDirectDrawSurface3 *iface)
37
{
38
    return CONTAINING_RECORD(iface, IDirectDrawSurfaceImpl, IDirectDrawSurface3_iface);
39
}
40 41 42

static IDirectDrawSurfaceImpl *unsafe_impl_from_IDirectDrawSurface3(IDirectDrawSurface3 *iface);

43
static IDirectDrawSurfaceImpl *impl_from_IDirectDrawSurface4(IDirectDrawSurface4 *iface)
44
{
45
    return CONTAINING_RECORD(iface, IDirectDrawSurfaceImpl, IDirectDrawSurface4_iface);
46 47
}

48 49
static HRESULT WINAPI IDirectDrawSurface4Impl_QueryInterface(IDirectDrawSurface4 *iface,
        REFIID riid, void **obj)
50
{
51
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface4(iface);
52 53 54 55 56 57 58 59 60 61

    *obj = NULL;

    if(!riid)
        return DDERR_INVALIDPARAMS;

    TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(riid),obj);
    if (IsEqualGUID(riid, &IID_IUnknown)
     || IsEqualGUID(riid, &IID_IDirectDrawSurface4) )
    {
62 63
        *obj = &This->IDirectDrawSurface4_iface;
        IDirectDrawSurface4_AddRef(&This->IDirectDrawSurface4_iface);
64 65 66 67 68 69 70
        TRACE("(%p) returning IDirectDrawSurface4 interface at %p\n", This, *obj);
        return S_OK;
    }
    else if( IsEqualGUID(riid, &IID_IDirectDrawSurface3)
          || IsEqualGUID(riid, &IID_IDirectDrawSurface2)
          || IsEqualGUID(riid, &IID_IDirectDrawSurface) )
    {
71 72
        *obj = &This->IDirectDrawSurface3_iface;
        IDirectDrawSurface3_AddRef(&This->IDirectDrawSurface3_iface);
73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98
        TRACE("(%p) returning IDirectDrawSurface3 interface at %p\n", This, *obj);
        return S_OK;
    }
    else if( IsEqualGUID(riid, &IID_IDirectDrawGammaControl) )
    {
        FIXME("Implement IDirectDrawGammaControl in ddrawex\n");
    }
    else if( IsEqualGUID(riid, &IID_IDirect3DHALDevice)||
             IsEqualGUID(riid, &IID_IDirect3DRGBDevice) )
    {
        /* Most likely not supported */
        FIXME("Test IDirect3DDevice in ddrawex\n");
    }
    else if (IsEqualGUID( &IID_IDirect3DTexture, riid ) ||
             IsEqualGUID( &IID_IDirect3DTexture2, riid ))
    {
        FIXME("Implement IDirect3dTexture in ddrawex\n");
    }
    else
    {
        WARN("No interface\n");
    }

    return E_NOINTERFACE;
}

99 100
static HRESULT WINAPI IDirectDrawSurface3Impl_QueryInterface(IDirectDrawSurface3 *iface,
        REFIID riid, void **obj)
101
{
102
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface3(iface);
103
    TRACE("(%p)->(%s,%p): Thunking to IDirectDrawSurface4\n",This,debugstr_guid(riid),obj);
104
    return IDirectDrawSurface4_QueryInterface(&This->IDirectDrawSurface4_iface, riid, obj);
105 106
}

107
static ULONG WINAPI IDirectDrawSurface4Impl_AddRef(IDirectDrawSurface4 *iface)
108
{
109
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface4(iface);
110 111 112 113 114 115 116
    ULONG ref = InterlockedIncrement(&This->ref);

    TRACE("(%p) : incrementing refcount from %u.\n", This, ref - 1);

    return ref;
}

117
static ULONG WINAPI IDirectDrawSurface3Impl_AddRef(IDirectDrawSurface3 *iface)
118
{
119
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface3(iface);
120
    TRACE("(%p): Thunking to IDirectDrawSurface4\n", This);
121
    return IDirectDrawSurface4_AddRef(&This->IDirectDrawSurface4_iface);
122 123
}

124
static ULONG WINAPI IDirectDrawSurface4Impl_Release(IDirectDrawSurface4 *iface)
125
{
126
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface4(iface);
127 128 129 130 131 132 133 134 135 136 137 138 139 140
    ULONG ref = InterlockedDecrement(&This->ref);

    TRACE("(%p) : decrementing refcount to %u.\n", This, ref);

    if(ref == 0)
    {
        TRACE("Destroying object\n");
        IDirectDrawSurface4_FreePrivateData(This->parent, &IID_DDrawexPriv);
        IDirectDrawSurface4_Release(This->parent);
        HeapFree(GetProcessHeap(), 0, This);
    }
    return ref;
}

141
static ULONG WINAPI IDirectDrawSurface3Impl_Release(IDirectDrawSurface3 *iface)
142
{
143
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface3(iface);
144
    TRACE("(%p): Thunking to IDirectDrawSurface4\n", This);
145
    return IDirectDrawSurface4_Release(&This->IDirectDrawSurface4_iface);
146 147
}

148 149
static HRESULT WINAPI IDirectDrawSurface4Impl_AddAttachedSurface(IDirectDrawSurface4 *iface,
        IDirectDrawSurface4 *Attach_iface)
150
{
151
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface4(iface);
152
    IDirectDrawSurfaceImpl *attach = unsafe_impl_from_IDirectDrawSurface4(Attach_iface);
153 154 155 156
    TRACE("(%p)->(%p)\n", This, attach);
    return IDirectDrawSurface4_AddAttachedSurface(This->parent, attach->parent);
}

157 158
static HRESULT WINAPI IDirectDrawSurface3Impl_AddAttachedSurface(IDirectDrawSurface3 *iface,
        IDirectDrawSurface3 *Attach_iface)
159
{
160
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface3(iface);
161
    IDirectDrawSurfaceImpl *attach = unsafe_impl_from_IDirectDrawSurface3(Attach_iface);
162
    TRACE("(%p)->(%p): Thunking to IDirectDrawSurface4\n", This, attach);
163 164
    return IDirectDrawSurface4_AddAttachedSurface(&This->IDirectDrawSurface4_iface,
            attach ? &attach->IDirectDrawSurface4_iface : NULL);
165 166
}

167 168
static HRESULT WINAPI IDirectDrawSurface4Impl_AddOverlayDirtyRect(IDirectDrawSurface4 *iface,
        RECT *Rect)
169
{
170
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface4(iface);
171 172 173 174
    TRACE("(%p)->(%p)\n", This, Rect);
    return IDirectDrawSurface4_AddOverlayDirtyRect(This->parent, Rect);
}

175 176
static HRESULT WINAPI IDirectDrawSurface3Impl_AddOverlayDirtyRect(IDirectDrawSurface3 *iface,
        RECT *Rect)
177
{
178
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface3(iface);
179
    TRACE("(%p)->(%p): Thunking to IDirectDrawSurface4\n", This, Rect);
180
    return IDirectDrawSurface4_AddOverlayDirtyRect(&This->IDirectDrawSurface4_iface, Rect);
181 182
}

183 184 185 186
static HRESULT WINAPI IDirectDrawSurface4Impl_Blt(IDirectDrawSurface4 *iface, RECT *DestRect,
        IDirectDrawSurface4 *SrcSurface, RECT *SrcRect, DWORD Flags, DDBLTFX *DDBltFx)
{
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface4(iface);
187
    IDirectDrawSurfaceImpl *Src = unsafe_impl_from_IDirectDrawSurface4(SrcSurface);
188 189 190 191 192
    TRACE("(%p)->(%p,%p,%p,0x%08x,%p)\n", This, DestRect, Src, SrcRect, Flags, DDBltFx);
    return IDirectDrawSurface4_Blt(This->parent, DestRect, Src ? Src->parent : NULL,
                                   SrcRect, Flags, DDBltFx);
}

193 194
static HRESULT WINAPI IDirectDrawSurface3Impl_Blt(IDirectDrawSurface3 *iface, RECT *DestRect,
        IDirectDrawSurface3 *SrcSurface, RECT *SrcRect, DWORD Flags, DDBLTFX *DDBltFx)
195
{
196
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface3(iface);
197
    IDirectDrawSurfaceImpl *Src = unsafe_impl_from_IDirectDrawSurface3(SrcSurface);
198
    TRACE("(%p)->(%p,%p,%p,0x%08x,%p): Thunking to IDirectDrawSurface4\n", This, DestRect, Src, SrcRect, Flags, DDBltFx);
199 200
    return IDirectDrawSurface4_Blt(&This->IDirectDrawSurface4_iface, DestRect,
            Src ? &Src->IDirectDrawSurface4_iface : NULL, SrcRect, Flags, DDBltFx);
201 202
}

203 204
static HRESULT WINAPI IDirectDrawSurface4Impl_BltBatch(IDirectDrawSurface4 *iface,
        DDBLTBATCH *Batch, DWORD Count, DWORD Flags)
205
{
206
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface4(iface);
207 208 209 210
    TRACE("(%p)->(%p,%u,0x%08x)\n", This, Batch, Count, Flags);
    return IDirectDrawSurface4_BltBatch(This->parent, Batch, Count, Flags);
}

211 212
static HRESULT WINAPI IDirectDrawSurface3Impl_BltBatch(IDirectDrawSurface3 *iface,
        DDBLTBATCH *Batch, DWORD Count, DWORD Flags)
213
{
214
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface3(iface);
215
    TRACE("(%p)->(%p,%u,0x%08x): Thunking to IDirectDrawSurface4\n", This, Batch, Count, Flags);
216
    return IDirectDrawSurface4_BltBatch(&This->IDirectDrawSurface4_iface, Batch, Count, Flags);
217 218
}

219 220 221 222
static HRESULT WINAPI IDirectDrawSurface4Impl_BltFast(IDirectDrawSurface4 *iface, DWORD dstx,
        DWORD dsty, IDirectDrawSurface4 *Source, RECT *rsrc, DWORD trans)
{
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface4(iface);
223
    IDirectDrawSurfaceImpl *Src = unsafe_impl_from_IDirectDrawSurface4(Source);
224 225 226 227 228
    TRACE("(%p)->(%u,%u,%p,%p,0x%08x)\n", This, dstx, dsty, Src, rsrc, trans);
    return IDirectDrawSurface4_BltFast(This->parent, dstx, dsty, Src ? Src->parent : NULL,
                                       rsrc, trans);
}

229 230
static HRESULT WINAPI IDirectDrawSurface3Impl_BltFast(IDirectDrawSurface3 *iface, DWORD dstx,
        DWORD dsty, IDirectDrawSurface3 *Source, RECT *rsrc, DWORD trans)
231
{
232
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface3(iface);
233
    IDirectDrawSurfaceImpl *Src = unsafe_impl_from_IDirectDrawSurface3(Source);
234
    TRACE("(%p)->(%u,%u,%p,%p,0x%08x): Thunking to IDirectDrawSurface4\n", This, dstx, dsty, Src, rsrc, trans);
235 236
    return IDirectDrawSurface4_BltFast(&This->IDirectDrawSurface4_iface, dstx, dsty,
            Src ? &Src->IDirectDrawSurface4_iface : NULL, rsrc, trans);
237 238
}

239 240
static HRESULT WINAPI IDirectDrawSurface4Impl_DeleteAttachedSurface(IDirectDrawSurface4 *iface,
        DWORD Flags, IDirectDrawSurface4 *Attach)
241
{
242
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface4(iface);
243
    IDirectDrawSurfaceImpl *Att = unsafe_impl_from_IDirectDrawSurface4(Attach);
244 245 246 247 248
    TRACE("(%p)->(0x%08x,%p)\n", This, Flags, Att);
    return IDirectDrawSurface4_DeleteAttachedSurface(This->parent, Flags,
                                                     Att ? Att->parent : NULL);
}

249 250
static HRESULT WINAPI IDirectDrawSurface3Impl_DeleteAttachedSurface(IDirectDrawSurface3 *iface,
        DWORD Flags, IDirectDrawSurface3 *Attach)
251
{
252
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface3(iface);
253
    IDirectDrawSurfaceImpl *Att = unsafe_impl_from_IDirectDrawSurface3(Attach);
254
    TRACE("(%p)->(0x%08x,%p): Thunking to IDirectDrawSurface4\n", This, Flags, Att);
255 256
    return IDirectDrawSurface4_DeleteAttachedSurface(&This->IDirectDrawSurface4_iface, Flags,
            Att ? &Att->IDirectDrawSurface4_iface : NULL);
257 258 259 260 261 262 263 264 265 266 267
}

struct enumsurfaces_wrap
{
    LPDDENUMSURFACESCALLBACK2 orig_cb;
    void *orig_ctx;
};

static HRESULT WINAPI
enumsurfaces_wrap_cb(IDirectDrawSurface4 *surf, DDSURFACEDESC2 *desc, void *vctx)
{
268
    struct enumsurfaces_wrap *ctx = vctx;
269 270 271 272 273 274 275 276
    IDirectDrawSurface4 *outer = dds_get_outer(surf);

    TRACE("Returning outer surface %p for inner surface %p\n", outer, surf);
    IDirectDrawSurface4_AddRef(outer);
    IDirectDrawSurface4_Release(surf);
    return ctx->orig_cb(outer, desc, vctx);
}

277 278
static HRESULT WINAPI IDirectDrawSurface4Impl_EnumAttachedSurfaces(IDirectDrawSurface4 *iface,
        void *context, LPDDENUMSURFACESCALLBACK2 cb)
279
{
280
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface4(iface);
281 282 283 284 285 286 287 288 289 290 291 292 293 294
    struct enumsurfaces_wrap ctx;
    TRACE("(%p)->(%p,%p)\n", This, context, cb);

    ctx.orig_cb = cb;
    ctx.orig_ctx = context;
    return IDirectDrawSurface4_EnumAttachedSurfaces(This->parent, &ctx, enumsurfaces_wrap_cb);
}

struct enumsurfaces_thunk
{
    LPDDENUMSURFACESCALLBACK orig_cb;
    void *orig_ctx;
};

295 296
static HRESULT WINAPI enumsurfaces_thunk_cb(IDirectDrawSurface4 *surf, DDSURFACEDESC2 *desc2,
        void *vctx)
297
{
298
    IDirectDrawSurfaceImpl *This = unsafe_impl_from_IDirectDrawSurface4(surf);
299
    struct enumsurfaces_thunk *ctx = vctx;
300 301 302
    DDSURFACEDESC desc;

    TRACE("Thunking back to IDirectDrawSurface3\n");
303
    IDirectDrawSurface3_AddRef(&This->IDirectDrawSurface3_iface);
304 305
    IDirectDrawSurface3_Release(surf);
    DDSD2_to_DDSD(desc2, &desc);
306 307
    return ctx->orig_cb((IDirectDrawSurface *)&This->IDirectDrawSurface3_iface, &desc,
            ctx->orig_ctx);
308 309
}

310 311
static HRESULT WINAPI IDirectDrawSurface3Impl_EnumAttachedSurfaces(IDirectDrawSurface3 *iface,
        void *context, LPDDENUMSURFACESCALLBACK cb)
312
{
313
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface3(iface);
314 315 316 317 318
    struct enumsurfaces_thunk ctx;
    TRACE("(%p)->(%p,%p): Thunking to IDirectDraw4\n", This, context, cb);

    ctx.orig_cb = cb;
    ctx.orig_ctx = context;
319 320
    return IDirectDrawSurface4_EnumAttachedSurfaces(&This->IDirectDrawSurface4_iface, &ctx,
            enumsurfaces_thunk_cb);
321 322
}

323 324
static HRESULT WINAPI IDirectDrawSurface4Impl_EnumOverlayZOrders(IDirectDrawSurface4 *iface,
        DWORD Flags, void *context, LPDDENUMSURFACESCALLBACK2 cb)
325
{
326
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface4(iface);
327 328 329 330 331 332 333 334
    struct enumsurfaces_wrap ctx;
    TRACE("(%p)->(0x%08x,%p,%p)\n", This, Flags, context, cb);

    ctx.orig_cb = cb;
    ctx.orig_ctx = context;
    return IDirectDrawSurface4_EnumOverlayZOrders(This->parent, Flags, &ctx, enumsurfaces_wrap_cb);
}

335 336
static HRESULT WINAPI IDirectDrawSurface3Impl_EnumOverlayZOrders(IDirectDrawSurface3 *iface,
        DWORD Flags, void *context, LPDDENUMSURFACESCALLBACK cb)
337
{
338
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface3(iface);
339 340 341 342 343
    struct enumsurfaces_thunk ctx;
    TRACE("(%p)->(0x%08x,%p,%p): Thunking to IDirectDraw4\n", This, Flags, context, cb);

    ctx.orig_cb = cb;
    ctx.orig_ctx = context;
344 345
    return IDirectDrawSurface4_EnumOverlayZOrders(&This->IDirectDrawSurface4_iface, Flags, &ctx,
            enumsurfaces_thunk_cb);
346 347
}

348 349
static HRESULT WINAPI IDirectDrawSurface4Impl_Flip(IDirectDrawSurface4 *iface,
        IDirectDrawSurface4 *DestOverride, DWORD Flags)
350
{
351
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface4(iface);
352
    IDirectDrawSurfaceImpl *Dest = unsafe_impl_from_IDirectDrawSurface4(DestOverride);
353 354 355 356
    TRACE("(%p)->(%p,0x%08x)\n", This, Dest, Flags);
    return IDirectDrawSurface4_Flip(This->parent, Dest ? Dest->parent : NULL, Flags);
}

357 358
static HRESULT WINAPI IDirectDrawSurface3Impl_Flip(IDirectDrawSurface3 *iface,
        IDirectDrawSurface3 *DestOverride, DWORD Flags)
359
{
360
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface3(iface);
361
    IDirectDrawSurfaceImpl *Dest = unsafe_impl_from_IDirectDrawSurface3(DestOverride);
362
    TRACE("(%p)->(%p,0x%08x): Thunking to IDirectDrawSurface4\n", This, Dest, Flags);
363 364
    return IDirectDrawSurface4_Flip(&This->IDirectDrawSurface4_iface,
            Dest ? &Dest->IDirectDrawSurface4_iface : NULL, Flags);
365 366
}

367 368
static HRESULT WINAPI IDirectDrawSurface4Impl_GetAttachedSurface(IDirectDrawSurface4 *iface,
        DDSCAPS2 *Caps, IDirectDrawSurface4 **Surface)
369
{
370
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface4(iface);
371 372 373 374
    IDirectDrawSurface4 *inner = NULL;
    HRESULT hr;
    TRACE("(%p)->(%p,%p)\n", This, Caps, Surface);

375
    hr = IDirectDrawSurface4_GetAttachedSurface(This->parent, Caps, &inner);
376 377 378 379 380 381 382 383 384 385 386 387 388
    if(SUCCEEDED(hr))
    {
        *Surface = dds_get_outer(inner);
        IDirectDrawSurface4_AddRef(*Surface);
        IDirectDrawSurface4_Release(inner);
    }
    else
    {
        *Surface = NULL;
    }
    return hr;
}

389 390
static HRESULT WINAPI IDirectDrawSurface3Impl_GetAttachedSurface(IDirectDrawSurface3 *iface,
        DDSCAPS *Caps, IDirectDrawSurface3 **Surface)
391
{
392
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface3(iface);
393 394 395 396 397 398 399
    IDirectDrawSurface4 *surf4;
    DDSCAPS2 caps2;
    HRESULT hr;
    TRACE("(%p)->(%p,%p): Thunking to IDirectDrawSurface4\n", This, Caps, Surface);

    memset(&caps2, 0, sizeof(caps2));
    caps2.dwCaps = Caps->dwCaps;
400
    hr = IDirectDrawSurface4_GetAttachedSurface(&This->IDirectDrawSurface4_iface, &caps2, &surf4);
401 402 403 404 405 406 407 408 409 410 411 412
    if(SUCCEEDED(hr))
    {
        IDirectDrawSurface4_QueryInterface(surf4, &IID_IDirectDrawSurface3, (void **) Surface);
        IDirectDrawSurface4_Release(surf4);
    }
    else
    {
        *Surface = NULL;
    }
    return hr;
}

413
static HRESULT WINAPI IDirectDrawSurface4Impl_GetBltStatus(IDirectDrawSurface4 *iface, DWORD Flags)
414
{
415
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface4(iface);
416 417 418 419
    TRACE("(%p)->(0x%08x)\n", This, Flags);
    return IDirectDrawSurface4_GetBltStatus(This->parent, Flags);
}

420
static HRESULT WINAPI IDirectDrawSurface3Impl_GetBltStatus(IDirectDrawSurface3 *iface, DWORD Flags)
421
{
422
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface3(iface);
423
    TRACE("(%p)->(0x%08x): Thunking to IDirectDrawSurface4\n", This, Flags);
424
    return IDirectDrawSurface4_GetBltStatus(&This->IDirectDrawSurface4_iface, Flags);
425 426
}

427
static HRESULT WINAPI IDirectDrawSurface4Impl_GetCaps(IDirectDrawSurface4 *iface, DDSCAPS2 *Caps)
428
{
429
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface4(iface);
430 431 432 433
    TRACE("(%p)->(%p)\n", This, Caps);
    return IDirectDrawSurface4_GetCaps(This->parent, Caps);
}

434
static HRESULT WINAPI IDirectDrawSurface3Impl_GetCaps(IDirectDrawSurface3 *iface, DDSCAPS *Caps)
435
{
436
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface3(iface);
437 438 439 440 441 442
    DDSCAPS2 caps2;
    HRESULT hr;
    TRACE("(%p)->(%p): Thunking to IDirectDrawSurface4\n", This, Caps);

    memset(&caps2, 0, sizeof(caps2));
    memset(Caps, 0, sizeof(*Caps));
443
    hr = IDirectDrawSurface4_GetCaps(&This->IDirectDrawSurface4_iface, &caps2);
444 445 446 447
    Caps->dwCaps = caps2.dwCaps;
    return hr;
}

448 449
static HRESULT WINAPI IDirectDrawSurface4Impl_GetClipper(IDirectDrawSurface4 *iface,
        IDirectDrawClipper **Clipper)
450
{
451
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface4(iface);
452 453 454 455
    TRACE("(%p)->(%p)\n", This, Clipper);
    return IDirectDrawSurface4_GetClipper(This->parent, Clipper);
}

456 457
static HRESULT WINAPI IDirectDrawSurface3Impl_GetClipper(IDirectDrawSurface3 *iface,
        IDirectDrawClipper **Clipper)
458
{
459
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface3(iface);
460
    TRACE("(%p)->(%p): Thunking to IDirectDrawSurface4\n", This, Clipper);
461
    return IDirectDrawSurface4_GetClipper(&This->IDirectDrawSurface4_iface, Clipper);
462 463
}

464 465
static HRESULT WINAPI IDirectDrawSurface4Impl_GetColorKey(IDirectDrawSurface4 *iface, DWORD Flags,
        DDCOLORKEY *CKey)
466
{
467
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface4(iface);
468 469 470 471
    TRACE("(%p)->(0x%08x,%p)\n", This, Flags, CKey);
    return IDirectDrawSurface4_GetColorKey(This->parent, Flags, CKey);
}

472 473
static HRESULT WINAPI IDirectDrawSurface3Impl_GetColorKey(IDirectDrawSurface3 *iface, DWORD Flags,
        DDCOLORKEY *CKey)
474
{
475
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface3(iface);
476
    TRACE("(%p)->(0x%08x,%p): Thunking to IDirectDrawSurface4\n", This, Flags, CKey);
477
    return IDirectDrawSurface4_GetColorKey(&This->IDirectDrawSurface4_iface, Flags, CKey);
478 479
}

480
static HRESULT WINAPI IDirectDrawSurface4Impl_GetDC(IDirectDrawSurface4 *iface, HDC *hdc)
481
{
482
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface4(iface);
483
    TRACE("(%p)->(%p)\n", This, hdc);
484 485 486 487 488 489 490 491 492 493
    if(This->permanent_dc)
    {
        TRACE("Returning stored dc %p\n", This->hdc);
        *hdc = This->hdc;
        return DD_OK;
    }
    else
    {
        return IDirectDrawSurface4_GetDC(This->parent, hdc);
    }
494 495
}

496
static HRESULT WINAPI IDirectDrawSurface3Impl_GetDC(IDirectDrawSurface3 *iface, HDC *hdc)
497
{
498
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface3(iface);
499
    TRACE("(%p)->(%p): Thunking to IDirectDrawSurface4\n", This, hdc);
500
    return IDirectDrawSurface4_GetDC(&This->IDirectDrawSurface4_iface, hdc);
501 502
}

503
static HRESULT WINAPI IDirectDrawSurface4Impl_GetFlipStatus(IDirectDrawSurface4 *iface, DWORD Flags)
504
{
505
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface4(iface);
506 507 508 509
    TRACE("(%p)->(0x%08x)\n", This, Flags);
    return IDirectDrawSurface4_GetFlipStatus(This->parent, Flags);
}

510
static HRESULT WINAPI IDirectDrawSurface3Impl_GetFlipStatus(IDirectDrawSurface3 *iface, DWORD Flags)
511
{
512
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface3(iface);
513
    TRACE("(%p)->(0x%08x): Thunking to IDirectDrawSurface4\n", This, Flags);
514
    return IDirectDrawSurface4_GetFlipStatus(&This->IDirectDrawSurface4_iface, Flags);
515 516
}

517 518
static HRESULT WINAPI IDirectDrawSurface4Impl_GetOverlayPosition(IDirectDrawSurface4 *iface,
        LONG *X, LONG *Y)
519
{
520
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface4(iface);
521 522 523 524
    TRACE("(%p)->(%p,%p)\n", This, X, Y);
    return IDirectDrawSurface4_GetOverlayPosition(This->parent, X, Y);
}

525 526
static HRESULT WINAPI IDirectDrawSurface3Impl_GetOverlayPosition(IDirectDrawSurface3 *iface,
        LONG *X, LONG *Y)
527
{
528
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface3(iface);
529
    TRACE("(%p)->(%p,%p): Thunking to IDirectDrawSurface4\n", This, X, Y);
530
    return IDirectDrawSurface4_GetOverlayPosition(&This->IDirectDrawSurface4_iface, X, Y);
531 532
}

533 534
static HRESULT WINAPI IDirectDrawSurface4Impl_GetPalette(IDirectDrawSurface4 *iface,
        IDirectDrawPalette **Pal)
535
{
536
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface4(iface);
537 538 539 540
    TRACE("(%p)->(%p)\n", This, Pal);
    return IDirectDrawSurface4_GetPalette(This->parent, Pal);
}

541 542
static HRESULT WINAPI IDirectDrawSurface3Impl_GetPalette(IDirectDrawSurface3 *iface,
        IDirectDrawPalette **Pal)
543
{
544
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface3(iface);
545
    TRACE("(%p)->(%p): Thunking to IDirectDrawSurface4\n", This, Pal);
546
    return IDirectDrawSurface4_GetPalette(&This->IDirectDrawSurface4_iface, Pal);
547 548
}

549 550
static HRESULT WINAPI IDirectDrawSurface4Impl_GetPixelFormat(IDirectDrawSurface4 *iface,
        DDPIXELFORMAT *PixelFormat)
551
{
552
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface4(iface);
553 554 555 556
    TRACE("(%p)->(%p)\n", This, PixelFormat);
    return IDirectDrawSurface4_GetPixelFormat(This->parent, PixelFormat);
}

557 558
static HRESULT WINAPI IDirectDrawSurface3Impl_GetPixelFormat(IDirectDrawSurface3 *iface,
        DDPIXELFORMAT *PixelFormat)
559
{
560
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface3(iface);
561
    TRACE("(%p)->(%p): Thunking to IDirectDrawSurface4\n", This, PixelFormat);
562
    return IDirectDrawSurface4_GetPixelFormat(&This->IDirectDrawSurface4_iface, PixelFormat);
563 564
}

565 566
static HRESULT WINAPI IDirectDrawSurface4Impl_GetSurfaceDesc(IDirectDrawSurface4 *iface,
        DDSURFACEDESC2 *DDSD)
567
{
568
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface4(iface);
569
    HRESULT hr;
570
    TRACE("(%p)->(%p)\n", This, DDSD);
571 572 573 574 575 576 577 578 579
    hr = IDirectDrawSurface4_GetSurfaceDesc(This->parent, DDSD);

    if(SUCCEEDED(hr) && This->permanent_dc)
    {
        DDSD->ddsCaps.dwCaps |= DDSCAPS_VIDEOMEMORY;
        DDSD->ddsCaps.dwCaps &= ~DDSCAPS_OWNDC;
    }

    return hr;
580 581
}

582 583
static HRESULT WINAPI IDirectDrawSurface3Impl_GetSurfaceDesc(IDirectDrawSurface3 *iface,
        DDSURFACEDESC *DDSD)
584
{
585
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface3(iface);
586 587 588 589 590 591
    DDSURFACEDESC2 ddsd2;
    HRESULT hr;
    TRACE("(%p)->(%p): Thunking to IDirectDrawSurface4\n", This, DDSD);

    memset(&ddsd2, 0, sizeof(ddsd2));
    ddsd2.dwSize = sizeof(ddsd2);
592
    hr = IDirectDrawSurface4_GetSurfaceDesc(&This->IDirectDrawSurface4_iface, &ddsd2);
593 594 595 596
    DDSD2_to_DDSD(&ddsd2, DDSD);
    return hr;
}

597 598
static HRESULT WINAPI IDirectDrawSurface4Impl_Initialize(IDirectDrawSurface4 *iface,
        IDirectDraw *DD, DDSURFACEDESC2 *DDSD)
599
{
600
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface4(iface);
601 602 603 604 605 606 607 608 609 610 611 612 613 614 615
    IDirectDraw4 *outer_DD4;
    IDirectDraw4 *inner_DD4;
    IDirectDraw *inner_DD;
    HRESULT hr;
    TRACE("(%p)->(%p,%p)\n", This, DD, DDSD);

    IDirectDraw_QueryInterface(DD, &IID_IDirectDraw4, (void **) &outer_DD4);
    inner_DD4 = dd_get_inner(outer_DD4);
    IDirectDraw4_Release(outer_DD4);
    IDirectDraw4_QueryInterface(inner_DD4, &IID_IDirectDraw4, (void **) &inner_DD);
    hr = IDirectDrawSurface4_Initialize(This->parent, inner_DD, DDSD);
    IDirectDraw_Release(inner_DD);
    return hr;
}

616 617
static HRESULT WINAPI IDirectDrawSurface3Impl_Initialize(IDirectDrawSurface3 *iface,
        IDirectDraw *DD, DDSURFACEDESC *DDSD)
618
{
619
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface3(iface);
620 621 622
    DDSURFACEDESC2 ddsd2;
    TRACE("(%p)->(%p,%p): Thunking to IDirectDrawSurface4\n", This, DD, DDSD);
    DDSD_to_DDSD2(DDSD, &ddsd2);
623
    return IDirectDrawSurface4_Initialize(&This->IDirectDrawSurface4_iface, DD, &ddsd2);
624 625
}

626
static HRESULT WINAPI IDirectDrawSurface4Impl_IsLost(IDirectDrawSurface4 *iface)
627
{
628
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface4(iface);
629 630 631 632
    TRACE("(%p)\n", This);
    return IDirectDrawSurface4_IsLost(This->parent);
}

633
static HRESULT WINAPI IDirectDrawSurface3Impl_IsLost(IDirectDrawSurface3 *iface)
634
{
635
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface3(iface);
636
    TRACE("(%p): Thunking to IDirectDrawSurface4\n", This);
637
    return IDirectDrawSurface4_IsLost(&This->IDirectDrawSurface4_iface);
638 639
}

640 641
static HRESULT WINAPI IDirectDrawSurface4Impl_Lock(IDirectDrawSurface4 *iface, RECT *Rect,
        DDSURFACEDESC2 *DDSD, DWORD Flags, HANDLE h)
642
{
643
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface4(iface);
644
    HRESULT hr;
645
    TRACE("(%p)->(%p,%p,0x%08x,%p)\n", This, Rect, DDSD, Flags, h);
646 647 648 649 650 651 652 653 654
    hr = IDirectDrawSurface4_Lock(This->parent, Rect, DDSD, Flags, h);

    if(SUCCEEDED(hr) && This->permanent_dc)
    {
        DDSD->ddsCaps.dwCaps |= DDSCAPS_VIDEOMEMORY;
        DDSD->ddsCaps.dwCaps &= ~DDSCAPS_OWNDC;
    }

    return hr;
655 656
}

657 658
static HRESULT WINAPI IDirectDrawSurface3Impl_Lock(IDirectDrawSurface3 *iface, RECT *Rect,
        DDSURFACEDESC *DDSD, DWORD Flags, HANDLE h)
659
{
660
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface3(iface);
661 662 663 664 665
    DDSURFACEDESC2 ddsd2;
    HRESULT hr;
    TRACE("(%p)->(%p,%p,0x%08x,%p): Thunking to IDirectDrawSurface4\n", This, Rect, DDSD, Flags, h);
    memset(&ddsd2, 0, sizeof(ddsd2));
    ddsd2.dwSize = sizeof(ddsd2);
666
    hr = IDirectDrawSurface4_Lock(&This->IDirectDrawSurface4_iface, Rect, &ddsd2, Flags, h);
667 668 669 670
    DDSD2_to_DDSD(&ddsd2, DDSD);
    return hr;
}

671
static HRESULT WINAPI IDirectDrawSurface4Impl_ReleaseDC(IDirectDrawSurface4 *iface, HDC hdc)
672
{
673
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface4(iface);
674
    TRACE("(%p)->(%p)\n", This, hdc);
675 676 677 678 679 680 681 682 683
    if(This->permanent_dc)
    {
        TRACE("Surface has a permanent DC, not doing anything\n");
        return DD_OK;
    }
    else
    {
        return IDirectDrawSurface4_ReleaseDC(This->parent, hdc);
    }
684 685
}

686
static HRESULT WINAPI IDirectDrawSurface3Impl_ReleaseDC(IDirectDrawSurface3 *iface, HDC hdc)
687
{
688
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface3(iface);
689
    TRACE("(%p)->(%p): Thunking to IDirectDrawSurface4\n", This, hdc);
690
    return IDirectDrawSurface4_ReleaseDC(&This->IDirectDrawSurface4_iface, hdc);
691 692
}

693
static HRESULT WINAPI IDirectDrawSurface4Impl_Restore(IDirectDrawSurface4 *iface)
694
{
695
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface4(iface);
696 697 698 699
    TRACE("(%p)\n", This);
    return IDirectDrawSurface4_Restore(This->parent);
}

700
static HRESULT WINAPI IDirectDrawSurface3Impl_Restore(IDirectDrawSurface3 *iface)
701
{
702
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface3(iface);
703
    TRACE("(%p): Thunking to IDirectDrawSurface4\n", This);
704
    return IDirectDrawSurface4_Restore(&This->IDirectDrawSurface4_iface);
705 706
}

707 708
static HRESULT WINAPI IDirectDrawSurface4Impl_SetClipper(IDirectDrawSurface4 *iface,
        IDirectDrawClipper *Clipper)
709
{
710
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface4(iface);
711 712 713 714
    TRACE("(%p)->(%p)\n", This, Clipper);
    return IDirectDrawSurface4_SetClipper(This->parent, Clipper);
}

715 716
static HRESULT WINAPI IDirectDrawSurface3Impl_SetClipper(IDirectDrawSurface3 *iface,
        IDirectDrawClipper *Clipper)
717
{
718
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface3(iface);
719
    TRACE("(%p)->(%p): Thunking to IDirectDrawSurface4\n", This, Clipper);
720
    return IDirectDrawSurface4_SetClipper(&This->IDirectDrawSurface4_iface, Clipper);
721 722
}

723 724
static HRESULT WINAPI IDirectDrawSurface4Impl_SetColorKey(IDirectDrawSurface4 *iface, DWORD Flags,
        DDCOLORKEY *CKey)
725
{
726
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface4(iface);
727 728 729 730
    TRACE("(%p)->(0x%08x,%p)\n", This, Flags, CKey);
    return IDirectDrawSurface4_SetColorKey(This->parent, Flags, CKey);
}

731 732
static HRESULT WINAPI IDirectDrawSurface3Impl_SetColorKey(IDirectDrawSurface3 *iface, DWORD Flags,
        DDCOLORKEY *CKey)
733
{
734
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface3(iface);
735
    TRACE("(%p)->(0x%08x,%p): Thunking to IDirectDrawSurface4\n", This, Flags, CKey);
736
    return IDirectDrawSurface4_SetColorKey(&This->IDirectDrawSurface4_iface, Flags, CKey);
737 738
}

739 740
static HRESULT WINAPI IDirectDrawSurface4Impl_SetOverlayPosition(IDirectDrawSurface4 *iface,
        LONG X, LONG Y)
741
{
742
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface4(iface);
743 744 745 746
    TRACE("(%p)->(%u,%u)\n", This, X, Y);
    return IDirectDrawSurface4_SetOverlayPosition(This->parent, X, Y);
}

747 748
static HRESULT WINAPI IDirectDrawSurface3Impl_SetOverlayPosition(IDirectDrawSurface3 *iface,
        LONG X, LONG Y)
749
{
750
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface3(iface);
751
    TRACE("(%p)->(%u,%u): Thunking to IDirectDrawSurface4\n", This, X, Y);
752
    return IDirectDrawSurface4_SetOverlayPosition(&This->IDirectDrawSurface4_iface, X, Y);
753 754
}

755 756
static HRESULT WINAPI IDirectDrawSurface4Impl_SetPalette(IDirectDrawSurface4 *iface,
        IDirectDrawPalette *Pal)
757
{
758
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface4(iface);
759 760 761 762
    TRACE("(%p)->(%p)\n", This, Pal);
    return IDirectDrawSurface4_SetPalette(This->parent, Pal);
}

763 764
static HRESULT WINAPI IDirectDrawSurface3Impl_SetPalette(IDirectDrawSurface3 *iface,
        IDirectDrawPalette *Pal)
765
{
766
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface3(iface);
767
    TRACE("(%p)->(%p): Thunking to IDirectDrawSurface4\n", This, Pal);
768
    return IDirectDrawSurface4_SetPalette(&This->IDirectDrawSurface4_iface, Pal);
769 770
}

771
static HRESULT WINAPI IDirectDrawSurface4Impl_Unlock(IDirectDrawSurface4 *iface, RECT *pRect)
772
{
773
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface4(iface);
774 775 776 777
    TRACE("(%p)->(%p)\n", This, pRect);
    return IDirectDrawSurface4_Unlock(This->parent, pRect);
}

778
static HRESULT WINAPI IDirectDrawSurface3Impl_Unlock(IDirectDrawSurface3 *iface, void *data)
779
{
780
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface3(iface);
781
    TRACE("(%p)->(%p): Thunking to IDirectDrawSurface4\n", This, data);
782
    return IDirectDrawSurface4_Unlock(&This->IDirectDrawSurface4_iface, NULL);
783 784
}

785 786 787 788 789
static HRESULT WINAPI IDirectDrawSurface4Impl_UpdateOverlay(IDirectDrawSurface4 *iface,
        RECT *SrcRect, IDirectDrawSurface4 *DstSurface, RECT *DstRect, DWORD Flags,
        DDOVERLAYFX *FX)
{
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface4(iface);
790
    IDirectDrawSurfaceImpl *Dst = unsafe_impl_from_IDirectDrawSurface4(DstSurface);
791 792 793 794 795
    TRACE("(%p)->(%p,%p,%p,0x%08x,%p)\n", This, SrcRect, Dst, DstRect, Flags, FX);
    return IDirectDrawSurface4_UpdateOverlay(This->parent, SrcRect, Dst ? Dst->parent : NULL,
                                             DstRect, Flags, FX);
}

796
static HRESULT WINAPI IDirectDrawSurface3Impl_UpdateOverlay(IDirectDrawSurface3 *iface,
797 798
        RECT *SrcRect, IDirectDrawSurface3 *DstSurface, RECT *DstRect, DWORD Flags,
        DDOVERLAYFX *FX)
799
{
800
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface3(iface);
801
    IDirectDrawSurfaceImpl *Dst = unsafe_impl_from_IDirectDrawSurface3(DstSurface);
802
    TRACE("(%p)->(%p,%p,%p,0x%08x,%p): Thunking to IDirectDrawSurface4\n", This, SrcRect, Dst, DstRect, Flags, FX);
803 804
    return IDirectDrawSurface4_UpdateOverlay(&This->IDirectDrawSurface4_iface, SrcRect,
            Dst ? &Dst->IDirectDrawSurface4_iface : NULL, DstRect, Flags, FX);
805 806
}

807 808
static HRESULT WINAPI IDirectDrawSurface4Impl_UpdateOverlayDisplay(IDirectDrawSurface4 *iface,
        DWORD Flags)
809
{
810
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface4(iface);
811 812 813 814
    TRACE("(%p)->(0x%08x)\n", This, Flags);
    return IDirectDrawSurface4_UpdateOverlayDisplay(This->parent, Flags);
}

815 816
static HRESULT WINAPI IDirectDrawSurface3Impl_UpdateOverlayDisplay(IDirectDrawSurface3 *iface,
        DWORD Flags)
817
{
818
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface3(iface);
819
    TRACE("(%p)->(0x%08x): Thunking to IDirectDrawSurface4\n", This, Flags);
820
    return IDirectDrawSurface4_UpdateOverlayDisplay(&This->IDirectDrawSurface4_iface, Flags);
821 822
}

823 824
static HRESULT WINAPI IDirectDrawSurface4Impl_UpdateOverlayZOrder(IDirectDrawSurface4 *iface,
        DWORD Flags, IDirectDrawSurface4 *DDSRef)
825
{
826
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface4(iface);
827
    IDirectDrawSurfaceImpl *Ref = unsafe_impl_from_IDirectDrawSurface4(DDSRef);
828 829 830 831
    TRACE("(%p)->(0x%08x,%p)\n", This, Flags, Ref);
    return IDirectDrawSurface4_UpdateOverlayZOrder(This->parent, Flags, Ref ? Ref->parent : NULL);
}

832 833
static HRESULT WINAPI IDirectDrawSurface3Impl_UpdateOverlayZOrder(IDirectDrawSurface3 *iface,
        DWORD Flags, IDirectDrawSurface3 *DDSRef)
834
{
835
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface3(iface);
836
    IDirectDrawSurfaceImpl *Ref = unsafe_impl_from_IDirectDrawSurface3(DDSRef);
837
    TRACE("(%p)->(0x%08x,%p): Thunking to IDirectDrawSurface4\n", This, Flags, Ref);
838 839
    return IDirectDrawSurface4_UpdateOverlayZOrder(&This->IDirectDrawSurface4_iface, Flags,
            Ref ? &Ref->IDirectDrawSurface4_iface : NULL);
840 841
}

842
static HRESULT WINAPI IDirectDrawSurface4Impl_GetDDInterface(IDirectDrawSurface4 *iface, void **DD)
843
{
844
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface4(iface);
845 846 847 848 849 850 851 852
    FIXME("(%p)->(%p)\n", This, DD);
    /* This has to be implemented in ddrawex, DDraw's interface can't be used because it is pretty
     * hard to tell which version of the DD interface is returned
     */
    *DD = NULL;
    return E_FAIL;
}

853
static HRESULT WINAPI IDirectDrawSurface3Impl_GetDDInterface(IDirectDrawSurface3 *iface, void **DD)
854
{
855
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface3(iface);
856 857 858 859 860 861 862
    FIXME("(%p)->(%p)\n", This, DD);
    /* A thunk it pretty pointless because of the same reason relaying to ddraw.dll works badly
     */
    *DD = NULL;
    return E_FAIL;
}

863
static HRESULT WINAPI IDirectDrawSurface4Impl_PageLock(IDirectDrawSurface4 *iface, DWORD Flags)
864
{
865
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface4(iface);
866 867 868 869
    TRACE("(%p)->(%x)\n", iface, Flags);
    return IDirectDrawSurface4_PageLock(This->parent, Flags);
}

870
static HRESULT WINAPI IDirectDrawSurface3Impl_PageLock(IDirectDrawSurface3 *iface, DWORD Flags)
871
{
872
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface3(iface);
873
    TRACE("(%p)->(%x): Thunking to IDirectDrawSurface4\n", iface, Flags);
874
    return IDirectDrawSurface4_PageLock(&This->IDirectDrawSurface4_iface, Flags);
875 876
}

877
static HRESULT WINAPI IDirectDrawSurface4Impl_PageUnlock(IDirectDrawSurface4 *iface, DWORD Flags)
878
{
879
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface4(iface);
880 881 882 883
    TRACE("(%p)->(%x)\n", iface, Flags);
    return IDirectDrawSurface4_PageUnlock(This->parent, Flags);
}

884
static HRESULT WINAPI IDirectDrawSurface3Impl_PageUnlock(IDirectDrawSurface3 *iface, DWORD Flags)
885
{
886
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface3(iface);
887
    TRACE("(%p)->(%x): Thunking to IDirectDrawSurface4\n", iface, Flags);
888
    return IDirectDrawSurface4_PageUnlock(&This->IDirectDrawSurface4_iface, Flags);
889 890
}

891 892
static HRESULT WINAPI IDirectDrawSurface4Impl_SetSurfaceDesc(IDirectDrawSurface4 *iface,
        DDSURFACEDESC2 *DDSD, DWORD Flags)
893
{
894
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface4(iface);
895 896 897 898
    TRACE("(%p)->(%p,0x%08x)\n", This, DDSD, Flags);
    return IDirectDrawSurface4_SetSurfaceDesc(This->parent, DDSD, Flags);
}

899 900
static HRESULT WINAPI IDirectDrawSurface3Impl_SetSurfaceDesc(IDirectDrawSurface3 *iface,
        DDSURFACEDESC *DDSD, DWORD Flags)
901
{
902
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface3(iface);
903 904 905 906
    DDSURFACEDESC2 ddsd;
    TRACE("(%p)->(%p,0x%08x): Thunking to IDirectDrawSurface4\n", This, DDSD, Flags);

    DDSD_to_DDSD2(DDSD, &ddsd);
907
    return IDirectDrawSurface4_SetSurfaceDesc(&This->IDirectDrawSurface4_iface, &ddsd, Flags);
908 909
}

910 911
static HRESULT WINAPI IDirectDrawSurface4Impl_SetPrivateData(IDirectDrawSurface4 *iface,
        REFGUID tag, void *Data, DWORD Size, DWORD Flags)
912
{
913
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface4(iface);
914 915 916 917 918 919 920 921 922 923
    TRACE("(%p)->(%s,%p,%u,0x%08x)\n", iface, debugstr_guid(tag), Data, Size, Flags);

    /* To completely avoid this we'd have to clone the private data API in ddrawex */
    if(IsEqualGUID(&IID_DDrawexPriv, tag)) {
        FIXME("Application uses ddrawex's private guid\n");
    }

    return IDirectDrawSurface4_SetPrivateData(This->parent, tag, Data, Size, Flags);
}

924 925
static HRESULT WINAPI IDirectDrawSurface4Impl_GetPrivateData(IDirectDrawSurface4 *iface,
        REFGUID tag, void *Data, DWORD *Size)
926
{
927
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface4(iface);
928 929 930 931 932 933 934 935 936 937
    TRACE("(%p)->(%s,%p,%p)\n", iface, debugstr_guid(tag), Data, Size);

    /* To completely avoid this we'd have to clone the private data API in ddrawex */
    if(IsEqualGUID(&IID_DDrawexPriv, tag)) {
        FIXME("Application uses ddrawex's private guid\n");
    }

    return IDirectDrawSurface4_GetPrivateData(This->parent, tag, Data, Size);
}

938 939
static HRESULT WINAPI IDirectDrawSurface4Impl_FreePrivateData(IDirectDrawSurface4 *iface,
        REFGUID tag)
940
{
941
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface4(iface);
942 943 944 945 946 947 948 949 950 951
    TRACE("(%p)->(%s)\n", iface, debugstr_guid(tag));

    /* To completely avoid this we'd have to clone the private data API in ddrawex */
    if(IsEqualGUID(&IID_DDrawexPriv, tag)) {
        FIXME("Application uses ddrawex's private guid\n");
    }

    return IDirectDrawSurface4_FreePrivateData(This->parent, tag);
}

952 953
static HRESULT WINAPI IDirectDrawSurface4Impl_GetUniquenessValue(IDirectDrawSurface4 *iface,
        DWORD *pValue)
954
{
955
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface4(iface);
956 957 958 959
    TRACE("(%p)->(%p)\n", This, pValue);
    return IDirectDrawSurface4_GetUniquenessValue(This->parent, pValue);
}

960
static HRESULT WINAPI IDirectDrawSurface4Impl_ChangeUniquenessValue(IDirectDrawSurface4 *iface)
961
{
962
    IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface4(iface);
963 964 965 966
    TRACE("(%p)\n", This);
    return IDirectDrawSurface4_ChangeUniquenessValue(This->parent);
}

967
static const IDirectDrawSurface3Vtbl IDirectDrawSurface3_Vtbl =
968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014
{
    /* IUnknown */
    IDirectDrawSurface3Impl_QueryInterface,
    IDirectDrawSurface3Impl_AddRef,
    IDirectDrawSurface3Impl_Release,
    /* IDirectDrawSurface */
    IDirectDrawSurface3Impl_AddAttachedSurface,
    IDirectDrawSurface3Impl_AddOverlayDirtyRect,
    IDirectDrawSurface3Impl_Blt,
    IDirectDrawSurface3Impl_BltBatch,
    IDirectDrawSurface3Impl_BltFast,
    IDirectDrawSurface3Impl_DeleteAttachedSurface,
    IDirectDrawSurface3Impl_EnumAttachedSurfaces,
    IDirectDrawSurface3Impl_EnumOverlayZOrders,
    IDirectDrawSurface3Impl_Flip,
    IDirectDrawSurface3Impl_GetAttachedSurface,
    IDirectDrawSurface3Impl_GetBltStatus,
    IDirectDrawSurface3Impl_GetCaps,
    IDirectDrawSurface3Impl_GetClipper,
    IDirectDrawSurface3Impl_GetColorKey,
    IDirectDrawSurface3Impl_GetDC,
    IDirectDrawSurface3Impl_GetFlipStatus,
    IDirectDrawSurface3Impl_GetOverlayPosition,
    IDirectDrawSurface3Impl_GetPalette,
    IDirectDrawSurface3Impl_GetPixelFormat,
    IDirectDrawSurface3Impl_GetSurfaceDesc,
    IDirectDrawSurface3Impl_Initialize,
    IDirectDrawSurface3Impl_IsLost,
    IDirectDrawSurface3Impl_Lock,
    IDirectDrawSurface3Impl_ReleaseDC,
    IDirectDrawSurface3Impl_Restore,
    IDirectDrawSurface3Impl_SetClipper,
    IDirectDrawSurface3Impl_SetColorKey,
    IDirectDrawSurface3Impl_SetOverlayPosition,
    IDirectDrawSurface3Impl_SetPalette,
    IDirectDrawSurface3Impl_Unlock,
    IDirectDrawSurface3Impl_UpdateOverlay,
    IDirectDrawSurface3Impl_UpdateOverlayDisplay,
    IDirectDrawSurface3Impl_UpdateOverlayZOrder,
    /* IDirectDrawSurface 2 */
    IDirectDrawSurface3Impl_GetDDInterface,
    IDirectDrawSurface3Impl_PageLock,
    IDirectDrawSurface3Impl_PageUnlock,
    /* IDirectDrawSurface 3 */
    IDirectDrawSurface3Impl_SetSurfaceDesc
};

1015
static const IDirectDrawSurface4Vtbl IDirectDrawSurface4_Vtbl =
1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068
{
    /*** IUnknown ***/
    IDirectDrawSurface4Impl_QueryInterface,
    IDirectDrawSurface4Impl_AddRef,
    IDirectDrawSurface4Impl_Release,
    /*** IDirectDrawSurface ***/
    IDirectDrawSurface4Impl_AddAttachedSurface,
    IDirectDrawSurface4Impl_AddOverlayDirtyRect,
    IDirectDrawSurface4Impl_Blt,
    IDirectDrawSurface4Impl_BltBatch,
    IDirectDrawSurface4Impl_BltFast,
    IDirectDrawSurface4Impl_DeleteAttachedSurface,
    IDirectDrawSurface4Impl_EnumAttachedSurfaces,
    IDirectDrawSurface4Impl_EnumOverlayZOrders,
    IDirectDrawSurface4Impl_Flip,
    IDirectDrawSurface4Impl_GetAttachedSurface,
    IDirectDrawSurface4Impl_GetBltStatus,
    IDirectDrawSurface4Impl_GetCaps,
    IDirectDrawSurface4Impl_GetClipper,
    IDirectDrawSurface4Impl_GetColorKey,
    IDirectDrawSurface4Impl_GetDC,
    IDirectDrawSurface4Impl_GetFlipStatus,
    IDirectDrawSurface4Impl_GetOverlayPosition,
    IDirectDrawSurface4Impl_GetPalette,
    IDirectDrawSurface4Impl_GetPixelFormat,
    IDirectDrawSurface4Impl_GetSurfaceDesc,
    IDirectDrawSurface4Impl_Initialize,
    IDirectDrawSurface4Impl_IsLost,
    IDirectDrawSurface4Impl_Lock,
    IDirectDrawSurface4Impl_ReleaseDC,
    IDirectDrawSurface4Impl_Restore,
    IDirectDrawSurface4Impl_SetClipper,
    IDirectDrawSurface4Impl_SetColorKey,
    IDirectDrawSurface4Impl_SetOverlayPosition,
    IDirectDrawSurface4Impl_SetPalette,
    IDirectDrawSurface4Impl_Unlock,
    IDirectDrawSurface4Impl_UpdateOverlay,
    IDirectDrawSurface4Impl_UpdateOverlayDisplay,
    IDirectDrawSurface4Impl_UpdateOverlayZOrder,
    /*** IDirectDrawSurface2 ***/
    IDirectDrawSurface4Impl_GetDDInterface,
    IDirectDrawSurface4Impl_PageLock,
    IDirectDrawSurface4Impl_PageUnlock,
    /*** IDirectDrawSurface3 ***/
    IDirectDrawSurface4Impl_SetSurfaceDesc,
    /*** IDirectDrawSurface4 ***/
    IDirectDrawSurface4Impl_SetPrivateData,
    IDirectDrawSurface4Impl_GetPrivateData,
    IDirectDrawSurface4Impl_FreePrivateData,
    IDirectDrawSurface4Impl_GetUniquenessValue,
    IDirectDrawSurface4Impl_ChangeUniquenessValue,
};

1069 1070 1071 1072
static IDirectDrawSurfaceImpl *unsafe_impl_from_IDirectDrawSurface3(IDirectDrawSurface3 *iface)
{
    if (!iface) return NULL;
    if (iface->lpVtbl != &IDirectDrawSurface3_Vtbl) return NULL;
1073
    return CONTAINING_RECORD(iface, IDirectDrawSurfaceImpl, IDirectDrawSurface3_iface);
1074 1075
}

1076 1077 1078 1079
IDirectDrawSurfaceImpl *unsafe_impl_from_IDirectDrawSurface4(IDirectDrawSurface4 *iface)
{
    if (!iface) return NULL;
    if (iface->lpVtbl != &IDirectDrawSurface4_Vtbl) return NULL;
1080
    return impl_from_IDirectDrawSurface4(iface);
1081 1082
}

1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110
/* dds_get_outer
 *
 * Given a surface from ddraw.dll it retrieves the pointer to the ddrawex.dll wrapper around it
 *
 * Parameters:
 *  inner: ddraw.dll surface to retrieve the outer surface from
 *
 * Returns:
 *  The surface wrapper. If there is none yet, a new one is created
 */
IDirectDrawSurface4 *dds_get_outer(IDirectDrawSurface4 *inner)
{
    IDirectDrawSurface4 *outer = NULL;
    DWORD size = sizeof(outer);
    HRESULT hr;
    if(!inner) return NULL;

    hr = IDirectDrawSurface4_GetPrivateData(inner,
                                            &IID_DDrawexPriv,
                                            &outer,
                                            &size);
    if(FAILED(hr) || outer == NULL)
    {
        IDirectDrawSurfaceImpl *impl;

        TRACE("Creating new ddrawex surface wrapper for surface %p\n", inner);
        impl = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*impl));
        impl->ref = 1;
1111
        impl->IDirectDrawSurface3_iface.lpVtbl = &IDirectDrawSurface3_Vtbl;
1112
        impl->IDirectDrawSurface4_iface.lpVtbl = &IDirectDrawSurface4_Vtbl;
1113 1114 1115
        IDirectDrawSurface4_AddRef(inner);
        impl->parent = inner;

1116
        outer = &impl->IDirectDrawSurface4_iface;
1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131

        hr = IDirectDrawSurface4_SetPrivateData(inner,
                                                &IID_DDrawexPriv,
                                                &outer,
                                                sizeof(outer),
                                                0 /* Flags */);
        if(FAILED(hr))
        {
            ERR("IDirectDrawSurface4_SetPrivateData failed\n");
        }
    }

    return outer;
}

1132 1133
HRESULT prepare_permanent_dc(IDirectDrawSurface4 *iface)
{
1134
    IDirectDrawSurfaceImpl *This = unsafe_impl_from_IDirectDrawSurface4(iface);
1135 1136 1137 1138 1139 1140 1141 1142
    HRESULT hr;
    This->permanent_dc = TRUE;

    hr = IDirectDrawSurface4_GetDC(This->parent, &This->hdc);
    if(FAILED(hr)) return hr;
    hr = IDirectDrawSurface4_ReleaseDC(This->parent, This->hdc);
    return hr;
}