gdi32: Store a separate flag to mark a GDI object for delayed destruction.
[wine] / dlls / ddraw / surface_thunks.c
1 /* IDirectDrawSurface3 -> IDirectDrawSurface7 thunks
2  * Copyright 2000 TransGaming Technologies Inc.
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17  */
18
19 #include "config.h"
20 #include "wine/port.h"
21 #include "wine/debug.h"
22 #include <stdarg.h>
23 #include <assert.h>
24
25 #include "windef.h"
26 #include "winbase.h"
27 #include "wingdi.h"
28 #include "ddraw.h"
29 #include "winerror.h"
30
31 #include "ddraw_private.h"
32
33 WINE_DEFAULT_DEBUG_CHANNEL(ddraw_thunk);
34 WINE_DECLARE_DEBUG_CHANNEL(ddraw);
35
36 static HRESULT WINAPI
37 IDirectDrawSurface3Impl_QueryInterface(LPDIRECTDRAWSURFACE3 This, REFIID iid,
38                                        LPVOID *ppObj)
39 {
40     return IDirectDrawSurface7_QueryInterface((IDirectDrawSurface7 *)surface_from_surface3(This), iid, ppObj);
41 }
42
43 static ULONG WINAPI
44 IDirectDrawSurface3Impl_AddRef(LPDIRECTDRAWSURFACE3 This)
45 {
46     return IDirectDrawSurface7_AddRef((IDirectDrawSurface7 *)surface_from_surface3(This));
47 }
48
49 static ULONG WINAPI
50 IDirectDrawSurface3Impl_Release(LPDIRECTDRAWSURFACE3 iface)
51 {
52     IDirectDrawSurfaceImpl *This = surface_from_surface3(iface);
53     TRACE("(%p)\n", This);
54     return IDirectDrawSurface7_Release((IDirectDrawSurface7 *)surface_from_surface3(iface));
55 }
56
57 static HRESULT WINAPI
58 IDirectDrawSurface3Impl_AddAttachedSurface(LPDIRECTDRAWSURFACE3 iface,
59                                            LPDIRECTDRAWSURFACE3 pAttach)
60 {
61     IDirectDrawSurfaceImpl *This = surface_from_surface3(iface);
62     IDirectDrawSurfaceImpl *Surf = surface_from_surface3(pAttach);
63     TRACE("(%p)->(%p)\n", This, Surf);
64
65     /* Tests suggest that
66      * -> offscreen plain surfaces can be attached to other offscreen plain surfaces
67      * -> offscreen plain surfaces can be attached to primaries
68      * -> primaries can be attached to offscreen plain surfaces
69      * -> z buffers can be attached to primaries
70      *
71      */
72     if(This->surface_desc.ddsCaps.dwCaps & (DDSCAPS_PRIMARYSURFACE | DDSCAPS_OFFSCREENPLAIN) &&
73        Surf->surface_desc.ddsCaps.dwCaps & (DDSCAPS_PRIMARYSURFACE | DDSCAPS_OFFSCREENPLAIN))
74     {
75         /* Sizes have to match */
76         if(Surf->surface_desc.dwWidth != This->surface_desc.dwWidth ||
77         Surf->surface_desc.dwHeight != This->surface_desc.dwHeight)
78         {
79             WARN("Surface sizes do not match\n");
80             return DDERR_CANNOTATTACHSURFACE;
81         }
82         /* OK */
83     }
84     else if(This->surface_desc.ddsCaps.dwCaps & (DDSCAPS_PRIMARYSURFACE | DDSCAPS_3DDEVICE) &&
85             Surf->surface_desc.ddsCaps.dwCaps & (DDSCAPS_ZBUFFER))
86     {
87         /* OK */
88     }
89     else
90     {
91         WARN("Invalid attachment combination\n");
92         return DDERR_CANNOTATTACHSURFACE;
93     }
94
95     return IDirectDrawSurfaceImpl_AddAttachedSurface(This,
96                                                      Surf);
97 }
98
99 static HRESULT WINAPI
100 IDirectDrawSurface3Impl_AddOverlayDirtyRect(LPDIRECTDRAWSURFACE3 This,
101                                             LPRECT pRect)
102 {
103     return IDirectDrawSurface7_AddOverlayDirtyRect((IDirectDrawSurface7 *)surface_from_surface3(This), pRect);
104 }
105
106 static HRESULT WINAPI
107 IDirectDrawSurface3Impl_Blt(LPDIRECTDRAWSURFACE3 This, LPRECT prcDst,
108                             LPDIRECTDRAWSURFACE3 pSrcSurf, LPRECT prcSrc,
109                             DWORD dwFlags, LPDDBLTFX pFX)
110 {
111     return IDirectDrawSurface7_Blt((IDirectDrawSurface7 *)surface_from_surface3(This), prcDst,
112             pSrcSurf ? (IDirectDrawSurface7 *)surface_from_surface3(pSrcSurf) : NULL, prcSrc, dwFlags, pFX);
113 }
114
115 static HRESULT WINAPI
116 IDirectDrawSurface3Impl_BltBatch(LPDIRECTDRAWSURFACE3 This,
117                                  LPDDBLTBATCH pBatch, DWORD dwCount,
118                                  DWORD dwFlags)
119 {
120     return IDirectDrawSurface7_BltBatch((IDirectDrawSurface7 *)surface_from_surface3(This), pBatch, dwCount, dwFlags);
121 }
122
123 static HRESULT WINAPI
124 IDirectDrawSurface3Impl_BltFast(LPDIRECTDRAWSURFACE3 This, DWORD x, DWORD y,
125                                 LPDIRECTDRAWSURFACE3 pSrcSurf, LPRECT prcSrc,
126                                 DWORD dwTrans)
127 {
128     return IDirectDrawSurface7_BltFast((IDirectDrawSurface7 *)surface_from_surface3(This), x, y,
129             pSrcSurf ? (IDirectDrawSurface7 *)surface_from_surface3(pSrcSurf) : NULL, prcSrc, dwTrans);
130 }
131
132 static HRESULT WINAPI
133 IDirectDrawSurface3Impl_DeleteAttachedSurface(LPDIRECTDRAWSURFACE3 This,
134                                               DWORD dwFlags,
135                                               LPDIRECTDRAWSURFACE3 pAttached)
136 {
137     return IDirectDrawSurface7_DeleteAttachedSurface((IDirectDrawSurface7 *)surface_from_surface3(This), dwFlags,
138             pAttached ? (IDirectDrawSurface7 *)surface_from_surface3(pAttached) : NULL);
139 }
140
141 struct callback_info
142 {
143     LPDDENUMSURFACESCALLBACK callback;
144     LPVOID context;
145 };
146
147 static HRESULT CALLBACK
148 EnumCallback(LPDIRECTDRAWSURFACE7 iface, LPDDSURFACEDESC2 pDDSD,
149              LPVOID context)
150 {
151     const struct callback_info* info = context;
152
153 #if 0
154     /* This is an outgoing conversion so we have to do it. */
155     DDSURFACEDESC ddsd;
156     memset(&ddsd, 0, sizeof(ddsd));
157     ddsd.dwSize = sizeof(ddsd);
158     DDRAW_Convert_DDSURFACEDESC_2_To_1(pDDSD, &ddsd);
159 #endif
160
161     /* the LPDDSURFACEDESC2 -> LPDDSURFACEDESC coercion is safe, since
162      * the data format is compatible with older enum procs */
163     return info->callback(iface ?
164             (IDirectDrawSurface *)&((IDirectDrawSurfaceImpl *)iface)->IDirectDrawSurface3_vtbl : NULL,
165             (LPDDSURFACEDESC)pDDSD, info->context);
166 }
167
168 static HRESULT WINAPI
169 IDirectDrawSurface3Impl_EnumAttachedSurfaces(LPDIRECTDRAWSURFACE3 This,
170                                              LPVOID context,
171                                              LPDDENUMSURFACESCALLBACK callback)
172 {
173     struct callback_info info;
174
175     info.callback = callback;
176     info.context  = context;
177
178     return IDirectDrawSurface7_EnumAttachedSurfaces((IDirectDrawSurface7 *)surface_from_surface3(This),
179             &info, EnumCallback);
180 }
181
182 static HRESULT WINAPI
183 IDirectDrawSurface3Impl_EnumOverlayZOrders(LPDIRECTDRAWSURFACE3 This,
184                                            DWORD dwFlags, LPVOID context,
185                                            LPDDENUMSURFACESCALLBACK callback)
186 {
187     struct callback_info info;
188
189     info.callback = callback;
190     info.context  = context;
191
192     return IDirectDrawSurface7_EnumOverlayZOrders((IDirectDrawSurface7 *)surface_from_surface3(This),
193             dwFlags, &info, EnumCallback);
194 }
195
196 static HRESULT WINAPI
197 IDirectDrawSurface3Impl_Flip(LPDIRECTDRAWSURFACE3 This,
198                              LPDIRECTDRAWSURFACE3 pOverride, DWORD dwFlags)
199 {
200     return IDirectDrawSurface7_Flip((IDirectDrawSurface7 *)surface_from_surface3(This),
201             pOverride ? (IDirectDrawSurface7 *)surface_from_surface3(pOverride) : NULL, dwFlags);
202 }
203
204 static HRESULT WINAPI
205 IDirectDrawSurface3Impl_GetAttachedSurface(LPDIRECTDRAWSURFACE3 This,
206                                            LPDDSCAPS pCaps,
207                                            LPDIRECTDRAWSURFACE3* ppAttached)
208 {
209     DDSCAPS2 caps;
210     LPDIRECTDRAWSURFACE7 pAttached7;
211     HRESULT hr;
212
213     caps.dwCaps  = pCaps->dwCaps;
214     caps.dwCaps2 = 0;
215     caps.dwCaps3 = 0;
216     caps.dwCaps4 = 0;
217
218     hr = IDirectDrawSurface7_GetAttachedSurface((IDirectDrawSurface7 *)surface_from_surface3(This), &caps, &pAttached7);
219     if (FAILED(hr)) *ppAttached = NULL;
220     else *ppAttached = pAttached7 ?
221             (IDirectDrawSurface3 *)&((IDirectDrawSurfaceImpl *)pAttached7)->IDirectDrawSurface3_vtbl : NULL;
222     return hr;
223 }
224
225 static HRESULT WINAPI
226 IDirectDrawSurface3Impl_GetBltStatus(LPDIRECTDRAWSURFACE3 This, DWORD dwFlags)
227 {
228     return IDirectDrawSurface7_GetBltStatus((IDirectDrawSurface7 *)surface_from_surface3(This), dwFlags);
229 }
230
231 static HRESULT WINAPI
232 IDirectDrawSurface3Impl_GetCaps(LPDIRECTDRAWSURFACE3 This, LPDDSCAPS pCaps)
233 {
234     DDSCAPS2 caps;
235     HRESULT hr;
236
237     hr = IDirectDrawSurface7_GetCaps((IDirectDrawSurface7 *)surface_from_surface3(This), &caps);
238     if (FAILED(hr)) return hr;
239
240     pCaps->dwCaps = caps.dwCaps;
241     return hr;
242 }
243
244 static HRESULT WINAPI
245 IDirectDrawSurface3Impl_GetClipper(LPDIRECTDRAWSURFACE3 This,
246                                    LPDIRECTDRAWCLIPPER* ppClipper)
247 {
248     return IDirectDrawSurface7_GetClipper((IDirectDrawSurface7 *)surface_from_surface3(This), ppClipper);
249 }
250
251 static HRESULT WINAPI
252 IDirectDrawSurface3Impl_GetColorKey(LPDIRECTDRAWSURFACE3 This, DWORD dwFlags,
253                                     LPDDCOLORKEY pCKey)
254 {
255     return IDirectDrawSurface7_GetColorKey((IDirectDrawSurface7 *)surface_from_surface3(This), dwFlags, pCKey);
256 }
257
258 static HRESULT WINAPI
259 IDirectDrawSurface3Impl_GetDC(LPDIRECTDRAWSURFACE3 This, HDC* phDC)
260 {
261     return IDirectDrawSurface7_GetDC((IDirectDrawSurface7 *)surface_from_surface3(This), phDC);
262 }
263
264 static HRESULT WINAPI
265 IDirectDrawSurface3Impl_GetFlipStatus(LPDIRECTDRAWSURFACE3 This, DWORD dwFlags)
266 {
267     return IDirectDrawSurface7_GetFlipStatus((IDirectDrawSurface7 *)surface_from_surface3(This), dwFlags);
268 }
269
270 static HRESULT WINAPI
271 IDirectDrawSurface3Impl_GetOverlayPosition(LPDIRECTDRAWSURFACE3 This, LPLONG pX,
272                                        LPLONG pY)
273 {
274     return IDirectDrawSurface7_GetOverlayPosition((IDirectDrawSurface7 *)surface_from_surface3(This), pX, pY);
275 }
276
277 static HRESULT WINAPI
278 IDirectDrawSurface3Impl_GetPalette(LPDIRECTDRAWSURFACE3 This,
279                                    LPDIRECTDRAWPALETTE* ppPalette)
280 {
281     return IDirectDrawSurface7_GetPalette((IDirectDrawSurface7 *)surface_from_surface3(This), ppPalette);
282 }
283
284 static HRESULT WINAPI
285 IDirectDrawSurface3Impl_GetPixelFormat(LPDIRECTDRAWSURFACE3 This,
286                                        LPDDPIXELFORMAT pPixelFormat)
287 {
288     return IDirectDrawSurface7_GetPixelFormat((IDirectDrawSurface7 *)surface_from_surface3(This), pPixelFormat);
289 }
290
291 static HRESULT WINAPI
292 IDirectDrawSurface3Impl_GetSurfaceDesc(LPDIRECTDRAWSURFACE3 iface,
293                                        LPDDSURFACEDESC pDDSD)
294 {
295     IDirectDrawSurfaceImpl *This = surface_from_surface3(iface);
296
297     TRACE_(ddraw)("(%p)->(%p)\n",This,pDDSD);
298
299     if(!pDDSD)
300         return DDERR_INVALIDPARAMS;
301
302     if (pDDSD->dwSize != sizeof(DDSURFACEDESC))
303     {
304         WARN("Incorrect struct size %d, returning DDERR_INVALIDPARAMS\n",pDDSD->dwSize);
305         return DDERR_INVALIDPARAMS;
306     }
307
308     EnterCriticalSection(&ddraw_cs);
309     DD_STRUCT_COPY_BYSIZE(pDDSD,(DDSURFACEDESC *) &This->surface_desc);
310     TRACE("Returning surface desc:\n");
311     if (TRACE_ON(ddraw))
312     {
313         /* DDRAW_dump_surface_desc handles the smaller size */
314         DDRAW_dump_surface_desc((DDSURFACEDESC2 *) pDDSD);
315     }
316
317     LeaveCriticalSection(&ddraw_cs);
318     return DD_OK;
319 }
320
321 static HRESULT WINAPI
322 IDirectDrawSurface3Impl_Initialize(LPDIRECTDRAWSURFACE3 This, LPDIRECTDRAW pDD,
323                                    LPDDSURFACEDESC pDDSD)
324 {
325     return IDirectDrawSurface7_Initialize((IDirectDrawSurface7 *)surface_from_surface3(This),
326             pDD, (LPDDSURFACEDESC2)pDDSD);
327 }
328
329 static HRESULT WINAPI
330 IDirectDrawSurface3Impl_IsLost(LPDIRECTDRAWSURFACE3 This)
331 {
332     return IDirectDrawSurface7_IsLost((IDirectDrawSurface7 *)surface_from_surface3(This));
333 }
334
335 static HRESULT WINAPI
336 IDirectDrawSurface3Impl_Lock(LPDIRECTDRAWSURFACE3 This, LPRECT pRect,
337                              LPDDSURFACEDESC pDDSD, DWORD dwFlags, HANDLE h)
338 {
339     return IDirectDrawSurface7_Lock((IDirectDrawSurface7 *)surface_from_surface3(This),
340             pRect, (LPDDSURFACEDESC2)pDDSD, dwFlags, h);
341 }
342
343 static HRESULT WINAPI
344 IDirectDrawSurface3Impl_ReleaseDC(LPDIRECTDRAWSURFACE3 This, HDC hDC)
345 {
346     return IDirectDrawSurface7_ReleaseDC((IDirectDrawSurface7 *)surface_from_surface3(This), hDC);
347 }
348
349 static HRESULT WINAPI
350 IDirectDrawSurface3Impl_Restore(LPDIRECTDRAWSURFACE3 This)
351 {
352     return IDirectDrawSurface7_Restore((IDirectDrawSurface7 *)surface_from_surface3(This));
353 }
354
355 static HRESULT WINAPI
356 IDirectDrawSurface3Impl_SetClipper(LPDIRECTDRAWSURFACE3 This,
357                                    LPDIRECTDRAWCLIPPER pClipper)
358 {
359     return IDirectDrawSurface7_SetClipper((IDirectDrawSurface7 *)surface_from_surface3(This), pClipper);
360 }
361
362 static HRESULT WINAPI
363 IDirectDrawSurface3Impl_SetColorKey(LPDIRECTDRAWSURFACE3 This, DWORD dwFlags,
364                                     LPDDCOLORKEY pCKey)
365 {
366     return IDirectDrawSurface7_SetColorKey((IDirectDrawSurface7 *)surface_from_surface3(This), dwFlags, pCKey);
367 }
368
369 static HRESULT WINAPI
370 IDirectDrawSurface3Impl_SetOverlayPosition(LPDIRECTDRAWSURFACE3 This, LONG x,
371                                        LONG y)
372 {
373     return IDirectDrawSurface7_SetOverlayPosition((IDirectDrawSurface7 *)surface_from_surface3(This), x, y);
374 }
375
376 static HRESULT WINAPI
377 IDirectDrawSurface3Impl_SetPalette(LPDIRECTDRAWSURFACE3 This,
378                                    LPDIRECTDRAWPALETTE pPalette)
379 {
380     return IDirectDrawSurface7_SetPalette((IDirectDrawSurface7 *)surface_from_surface3(This), pPalette);
381 }
382
383 static HRESULT WINAPI
384 IDirectDrawSurface3Impl_Unlock(LPDIRECTDRAWSURFACE3 This, LPVOID data)
385 {
386     /* data might not be the LPRECT of later versions, so drop it. */
387     return IDirectDrawSurface7_Unlock((IDirectDrawSurface7 *)surface_from_surface3(This), NULL);
388 }
389
390 static HRESULT WINAPI
391 IDirectDrawSurface3Impl_UpdateOverlay(LPDIRECTDRAWSURFACE3 This, LPRECT prcSrc,
392                                       LPDIRECTDRAWSURFACE3 pDstSurf,
393                                       LPRECT prcDst, DWORD dwFlags,
394                                       LPDDOVERLAYFX pFX)
395 {
396     return IDirectDrawSurface7_UpdateOverlay((IDirectDrawSurface7 *)surface_from_surface3(This), prcSrc,
397             pDstSurf ? (IDirectDrawSurface7 *)surface_from_surface3(pDstSurf) : NULL, prcDst, dwFlags, pFX);
398 }
399
400 static HRESULT WINAPI
401 IDirectDrawSurface3Impl_UpdateOverlayDisplay(LPDIRECTDRAWSURFACE3 This,
402                                              DWORD dwFlags)
403 {
404     return IDirectDrawSurface7_UpdateOverlayDisplay((IDirectDrawSurface7 *)surface_from_surface3(This), dwFlags);
405 }
406
407 static HRESULT WINAPI
408 IDirectDrawSurface3Impl_UpdateOverlayZOrder(LPDIRECTDRAWSURFACE3 This,
409                                             DWORD dwFlags,
410                                             LPDIRECTDRAWSURFACE3 pSurfReference)
411 {
412     return IDirectDrawSurface7_UpdateOverlayZOrder((IDirectDrawSurface7 *)surface_from_surface3(This), dwFlags,
413             pSurfReference ? (IDirectDrawSurface7 *)surface_from_surface3(pSurfReference) : NULL);
414 }
415
416 static HRESULT WINAPI
417 IDirectDrawSurface3Impl_GetDDInterface(LPDIRECTDRAWSURFACE3 This, LPVOID* ppDD)
418 {
419     return IDirectDrawSurface7_GetDDInterface((IDirectDrawSurface7 *)surface_from_surface3(This), ppDD);
420 }
421
422 static HRESULT WINAPI
423 IDirectDrawSurface3Impl_PageLock(LPDIRECTDRAWSURFACE3 This, DWORD dwFlags)
424 {
425     return IDirectDrawSurface7_PageLock((IDirectDrawSurface7 *)surface_from_surface3(This), dwFlags);
426 }
427
428 static HRESULT WINAPI
429 IDirectDrawSurface3Impl_PageUnlock(LPDIRECTDRAWSURFACE3 This, DWORD dwFlags)
430 {
431     return IDirectDrawSurface7_PageUnlock((IDirectDrawSurface7 *)surface_from_surface3(This), dwFlags);
432 }
433
434 static HRESULT WINAPI
435 IDirectDrawSurface3Impl_SetSurfaceDesc(LPDIRECTDRAWSURFACE3 This,
436                                        LPDDSURFACEDESC pDDSD, DWORD dwFlags)
437 {
438     return IDirectDrawSurface7_SetSurfaceDesc((IDirectDrawSurface7 *)surface_from_surface3(This),
439             (LPDDSURFACEDESC2)pDDSD, dwFlags);
440 }
441
442 const IDirectDrawSurface3Vtbl IDirectDrawSurface3_Vtbl =
443 {
444     IDirectDrawSurface3Impl_QueryInterface,
445     IDirectDrawSurface3Impl_AddRef,
446     IDirectDrawSurface3Impl_Release,
447     IDirectDrawSurface3Impl_AddAttachedSurface,
448     IDirectDrawSurface3Impl_AddOverlayDirtyRect,
449     IDirectDrawSurface3Impl_Blt,
450     IDirectDrawSurface3Impl_BltBatch,
451     IDirectDrawSurface3Impl_BltFast,
452     IDirectDrawSurface3Impl_DeleteAttachedSurface,
453     IDirectDrawSurface3Impl_EnumAttachedSurfaces,
454     IDirectDrawSurface3Impl_EnumOverlayZOrders,
455     IDirectDrawSurface3Impl_Flip,
456     IDirectDrawSurface3Impl_GetAttachedSurface,
457     IDirectDrawSurface3Impl_GetBltStatus,
458     IDirectDrawSurface3Impl_GetCaps,
459     IDirectDrawSurface3Impl_GetClipper,
460     IDirectDrawSurface3Impl_GetColorKey,
461     IDirectDrawSurface3Impl_GetDC,
462     IDirectDrawSurface3Impl_GetFlipStatus,
463     IDirectDrawSurface3Impl_GetOverlayPosition,
464     IDirectDrawSurface3Impl_GetPalette,
465     IDirectDrawSurface3Impl_GetPixelFormat,
466     IDirectDrawSurface3Impl_GetSurfaceDesc,
467     IDirectDrawSurface3Impl_Initialize,
468     IDirectDrawSurface3Impl_IsLost,
469     IDirectDrawSurface3Impl_Lock,
470     IDirectDrawSurface3Impl_ReleaseDC,
471     IDirectDrawSurface3Impl_Restore,
472     IDirectDrawSurface3Impl_SetClipper,
473     IDirectDrawSurface3Impl_SetColorKey,
474     IDirectDrawSurface3Impl_SetOverlayPosition,
475     IDirectDrawSurface3Impl_SetPalette,
476     IDirectDrawSurface3Impl_Unlock,
477     IDirectDrawSurface3Impl_UpdateOverlay,
478     IDirectDrawSurface3Impl_UpdateOverlayDisplay,
479     IDirectDrawSurface3Impl_UpdateOverlayZOrder,
480     IDirectDrawSurface3Impl_GetDDInterface,
481     IDirectDrawSurface3Impl_PageLock,
482     IDirectDrawSurface3Impl_PageUnlock,
483     IDirectDrawSurface3Impl_SetSurfaceDesc
484 };