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