ReactOS 0.4.15-dev-5853-gcb454ef
surface.c
Go to the documentation of this file.
1/* DirectDraw Surface Implementation
2 *
3 * Copyright (c) 1997-2000 Marcus Meissner
4 * Copyright (c) 1998-2000 Lionel Ulmer
5 * Copyright (c) 2000-2001 TransGaming Technologies Inc.
6 * Copyright (c) 2006 Stefan Dösinger
7 * Copyright (c) 2011 Ričardas Barkauskas for CodeWeavers
8 *
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
13 *
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
18 *
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 */
23
24#include "config.h"
25#include "wine/port.h"
26
27#include "ddraw_private.h"
28
30
31static struct ddraw_surface *unsafe_impl_from_IDirectDrawSurface2(IDirectDrawSurface2 *iface);
32static struct ddraw_surface *unsafe_impl_from_IDirectDrawSurface3(IDirectDrawSurface3 *iface);
33
34static inline struct ddraw_surface *impl_from_IDirectDrawGammaControl(IDirectDrawGammaControl *iface)
35{
37}
38
39/* This is slow, of course. Also, in case of locks, we can't prevent other
40 * applications from drawing to the screen while we've locked the frontbuffer.
41 * We'd like to do this in wined3d instead, but for that to work wined3d needs
42 * to support windowless rendering first. */
43HRESULT ddraw_surface_update_frontbuffer(struct ddraw_surface *surface, const RECT *rect, BOOL read, unsigned int swap_interval)
44{
45 struct wined3d_texture *dst_texture;
46 struct ddraw *ddraw = surface->ddraw;
47 HDC surface_dc, screen_dc;
48 int x, y, w, h;
49 HRESULT hr;
50 BOOL ret;
51 RECT r;
52
53 if (!rect)
54 {
55 SetRect(&r, 0, 0, surface->surface_desc.dwWidth, surface->surface_desc.dwHeight);
56 rect = &r;
57 }
58
59 x = rect->left;
60 y = rect->top;
61 w = rect->right - rect->left;
62 h = rect->bottom - rect->top;
63
64 if (w <= 0 || h <= 0)
65 return DD_OK;
66
68 {
69 /* Nothing to do, we control the frontbuffer, or at least the parts we
70 * care about. */
71 if (read)
72 return DD_OK;
73
74 if (swap_interval)
76 else
77 dst_texture = ddraw->wined3d_frontbuffer;
78
79 if (SUCCEEDED(hr = wined3d_texture_blt(dst_texture, 0, rect,
83 }
84
85 return hr;
86 }
87
88 if (FAILED(hr = wined3d_texture_get_dc(surface->wined3d_texture, surface->sub_resource_idx, &surface_dc)))
89 {
90 ERR("Failed to get surface DC, hr %#x.\n", hr);
91 return hr;
92 }
93 if (surface->palette)
94 wined3d_palette_apply_to_dc(surface->palette->wined3d_palette, surface_dc);
95
96 if (!(screen_dc = GetDC(NULL)))
97 {
98 wined3d_texture_release_dc(surface->wined3d_texture, surface->sub_resource_idx, surface_dc);
99 ERR("Failed to get screen DC.\n");
100 return E_FAIL;
101 }
102
103 if (read)
104 ret = BitBlt(surface_dc, x, y, w, h,
105 screen_dc, x, y, SRCCOPY);
106 else
107 ret = BitBlt(screen_dc, x, y, w, h,
108 surface_dc, x, y, SRCCOPY);
109
110 ReleaseDC(NULL, screen_dc);
111 wined3d_texture_release_dc(surface->wined3d_texture, surface->sub_resource_idx, surface_dc);
112
113 if (!ret)
114 {
115 ERR("Failed to blit to/from screen.\n");
116 return E_FAIL;
117 }
118
119 return DD_OK;
120}
121
122/*****************************************************************************
123 * IUnknown parts follow
124 *****************************************************************************/
125
126/*****************************************************************************
127 * IDirectDrawSurface7::QueryInterface
128 *
129 * A normal QueryInterface implementation. For QueryInterface rules
130 * see ddraw.c, IDirectDraw7::QueryInterface. This method
131 * can Query IDirectDrawSurface interfaces in all version, IDirect3DTexture
132 * in all versions, the IDirectDrawGammaControl interface and it can
133 * create an IDirect3DDevice. (Uses IDirect3D7::CreateDevice)
134 *
135 * Params:
136 * riid: The interface id queried for
137 * obj: Address to write the pointer to
138 *
139 * Returns:
140 * S_OK on success
141 * E_NOINTERFACE if the requested interface wasn't found
142 *
143 *****************************************************************************/
145{
147
148 TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), obj);
149
150 /* According to COM docs, if the QueryInterface fails, obj should be set to NULL */
151 *obj = NULL;
152
153 if(!riid)
154 return DDERR_INVALIDPARAMS;
155
156 if (IsEqualGUID(riid, &IID_IDirectDrawSurface7))
157 {
158 IDirectDrawSurface7_AddRef(iface);
159 *obj = iface;
160 TRACE("(%p) returning IDirectDrawSurface7 interface at %p\n", This, *obj);
161 return S_OK;
162 }
163
164 if (IsEqualGUID(riid, &IID_IDirectDrawSurface4))
165 {
166 IDirectDrawSurface4_AddRef(&This->IDirectDrawSurface4_iface);
167 *obj = &This->IDirectDrawSurface4_iface;
168 TRACE("(%p) returning IDirectDrawSurface4 interface at %p\n", This, *obj);
169 return S_OK;
170 }
171
172 if (IsEqualGUID(riid, &IID_IDirectDrawSurface3))
173 {
174 IDirectDrawSurface3_AddRef(&This->IDirectDrawSurface3_iface);
175 *obj = &This->IDirectDrawSurface3_iface;
176 TRACE("(%p) returning IDirectDrawSurface3 interface at %p\n", This, *obj);
177 return S_OK;
178 }
179
180 if (IsEqualGUID(riid, &IID_IDirectDrawSurface2))
181 {
182 IDirectDrawSurface2_AddRef(&This->IDirectDrawSurface2_iface);
183 *obj = &This->IDirectDrawSurface2_iface;
184 TRACE("(%p) returning IDirectDrawSurface2 interface at %p\n", This, *obj);
185 return S_OK;
186 }
187
188 if (IsEqualGUID(riid, &IID_IDirectDrawSurface)
190 {
191 IDirectDrawSurface_AddRef(&This->IDirectDrawSurface_iface);
192 *obj = &This->IDirectDrawSurface_iface;
193 TRACE("(%p) returning IDirectDrawSurface interface at %p\n", This, *obj);
194 return S_OK;
195 }
196
197 if (IsEqualGUID(riid, &IID_IDirectDrawGammaControl))
198 {
199 IDirectDrawGammaControl_AddRef(&This->IDirectDrawGammaControl_iface);
200 *obj = &This->IDirectDrawGammaControl_iface;
201 TRACE("(%p) returning IDirectDrawGammaControl interface at %p\n", This, *obj);
202 return S_OK;
203 }
204
205 if (IsEqualGUID(riid, &IID_IDirectDrawColorControl))
206 {
207 WARN("Color control not implemented.\n");
208 *obj = NULL;
209 return E_NOINTERFACE;
210 }
211
212 if (This->version != 7)
213 {
215 || IsEqualGUID(riid, &IID_IDirect3DHALDevice)
216 || IsEqualGUID(riid, &IID_IDirect3DRGBDevice))
217 {
219 if (!This->device1)
220 {
221 HRESULT hr;
222
223 if (FAILED(hr = d3d_device_create(This->ddraw, riid, This, (IUnknown *)&This->IDirectDrawSurface_iface,
224 1, &This->device1, (IUnknown *)&This->IDirectDrawSurface_iface)))
225 {
226 This->device1 = NULL;
228 WARN("Failed to create device, hr %#x.\n", hr);
229 return hr;
230 }
231 }
233
234 IDirect3DDevice_AddRef(&This->device1->IDirect3DDevice_iface);
235 *obj = &This->device1->IDirect3DDevice_iface;
236 return S_OK;
237 }
238
239 if (IsEqualGUID(&IID_IDirect3DTexture2, riid))
240 {
241 IDirect3DTexture2_AddRef(&This->IDirect3DTexture2_iface);
242 *obj = &This->IDirect3DTexture2_iface;
243 return S_OK;
244 }
245
246 if (IsEqualGUID( &IID_IDirect3DTexture, riid ))
247 {
248 IDirect3DTexture2_AddRef(&This->IDirect3DTexture_iface);
249 *obj = &This->IDirect3DTexture_iface;
250 return S_OK;
251 }
252 }
253
254 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
255
256 if (This->version != 7)
257 return E_INVALIDARG;
258
259 return E_NOINTERFACE;
260}
261
262static HRESULT WINAPI ddraw_surface4_QueryInterface(IDirectDrawSurface4 *iface, REFIID riid, void **object)
263{
264 struct ddraw_surface *surface = impl_from_IDirectDrawSurface4(iface);
265
266 TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
267
269}
270
271static HRESULT WINAPI ddraw_surface3_QueryInterface(IDirectDrawSurface3 *iface, REFIID riid, void **object)
272{
273 struct ddraw_surface *surface = impl_from_IDirectDrawSurface3(iface);
274
275 TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
276
278}
279
280static HRESULT WINAPI ddraw_surface2_QueryInterface(IDirectDrawSurface2 *iface, REFIID riid, void **object)
281{
282 struct ddraw_surface *surface = impl_from_IDirectDrawSurface2(iface);
283
284 TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
285
287}
288
289static HRESULT WINAPI ddraw_surface1_QueryInterface(IDirectDrawSurface *iface, REFIID riid, void **object)
290{
291 struct ddraw_surface *surface = impl_from_IDirectDrawSurface(iface);
292
293 TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
294
296}
297
298static HRESULT WINAPI ddraw_gamma_control_QueryInterface(IDirectDrawGammaControl *iface,
299 REFIID riid, void **object)
300{
301 struct ddraw_surface *surface = impl_from_IDirectDrawGammaControl(iface);
302
303 TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
304
306}
307
308static HRESULT WINAPI d3d_texture2_QueryInterface(IDirect3DTexture2 *iface, REFIID riid, void **object)
309{
310 struct ddraw_surface *surface = impl_from_IDirect3DTexture2(iface);
311
312 TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
313
315}
316
317static HRESULT WINAPI d3d_texture1_QueryInterface(IDirect3DTexture *iface, REFIID riid, void **object)
318{
319 struct ddraw_surface *surface = impl_from_IDirect3DTexture(iface);
320
321 TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
322
324}
325
326static void ddraw_surface_add_iface(struct ddraw_surface *surface)
327{
329 TRACE("%p increasing iface count to %u.\n", surface, iface_count);
330
331 if (iface_count == 1)
332 {
333 if (surface->ifaceToRelease)
334 IUnknown_AddRef(surface->ifaceToRelease);
336 if (surface->wined3d_rtv)
340 }
341}
342
343/*****************************************************************************
344 * IDirectDrawSurface7::AddRef
345 *
346 * A normal addref implementation
347 *
348 * Returns:
349 * The new refcount
350 *
351 *****************************************************************************/
353{
355 ULONG refcount = InterlockedIncrement(&This->ref7);
356
357 TRACE("iface %p increasing refcount to %u.\n", iface, refcount);
358
359 if (refcount == 1)
360 {
362 }
363
364 return refcount;
365}
366
367static ULONG WINAPI ddraw_surface4_AddRef(IDirectDrawSurface4 *iface)
368{
370 ULONG refcount = InterlockedIncrement(&This->ref4);
371
372 TRACE("iface %p increasing refcount to %u.\n", iface, refcount);
373
374 if (refcount == 1)
375 {
377 }
378
379 return refcount;
380}
381
382static ULONG WINAPI ddraw_surface3_AddRef(IDirectDrawSurface3 *iface)
383{
385 ULONG refcount = InterlockedIncrement(&This->ref3);
386
387 TRACE("iface %p increasing refcount to %u.\n", iface, refcount);
388
389 if (refcount == 1)
390 {
392 }
393
394 return refcount;
395}
396
397static ULONG WINAPI ddraw_surface2_AddRef(IDirectDrawSurface2 *iface)
398{
400 ULONG refcount = InterlockedIncrement(&This->ref2);
401
402 TRACE("iface %p increasing refcount to %u.\n", iface, refcount);
403
404 if (refcount == 1)
405 {
407 }
408
409 return refcount;
410}
411
412static ULONG WINAPI ddraw_surface1_AddRef(IDirectDrawSurface *iface)
413{
415 ULONG refcount = InterlockedIncrement(&This->ref1);
416
417 TRACE("iface %p increasing refcount to %u.\n", iface, refcount);
418
419 if (refcount == 1)
420 {
422 }
423
424 return refcount;
425}
426
427static ULONG WINAPI ddraw_gamma_control_AddRef(IDirectDrawGammaControl *iface)
428{
430 ULONG refcount = InterlockedIncrement(&This->gamma_count);
431
432 TRACE("iface %p increasing refcount to %u.\n", iface, refcount);
433
434 if (refcount == 1)
435 {
437 }
438
439 return refcount;
440}
441
442static ULONG WINAPI d3d_texture2_AddRef(IDirect3DTexture2 *iface)
443{
444 struct ddraw_surface *surface = impl_from_IDirect3DTexture2(iface);
445
446 TRACE("iface %p.\n", iface);
447
448 return IUnknown_AddRef(surface->texture_outer);
449}
450
451static ULONG WINAPI d3d_texture1_AddRef(IDirect3DTexture *iface)
452{
453 struct ddraw_surface *surface = impl_from_IDirect3DTexture(iface);
454
455 TRACE("iface %p.\n", iface);
456
457 return IUnknown_AddRef(surface->texture_outer);
458}
459
460static HRESULT ddraw_surface_set_palette(struct ddraw_surface *surface, IDirectDrawPalette *palette)
461{
463 struct ddraw_palette *prev;
464
465 TRACE("iface %p, palette %p.\n", surface, palette);
466
467 if (palette_impl && palette_impl->flags & DDPCAPS_ALPHA
469 {
470 WARN("Alpha palette set on non-texture surface, returning DDERR_INVALIDSURFACETYPE.\n");
472 }
473
476
478
479 prev = surface->palette;
481 {
482 if (prev)
483 prev->flags &= ~DDPCAPS_PRIMARYSURFACE;
484 if (palette_impl)
485 palette_impl->flags |= DDPCAPS_PRIMARYSURFACE;
486 wined3d_swapchain_set_palette(surface->ddraw->wined3d_swapchain,
487 palette_impl ? palette_impl->wined3d_palette : NULL);
489 }
490 if (palette_impl)
491 IDirectDrawPalette_AddRef(&palette_impl->IDirectDrawPalette_iface);
492 if (prev)
493 IDirectDrawPalette_Release(&prev->IDirectDrawPalette_iface);
494 surface->palette = palette_impl;
495
497
498 return DD_OK;
499}
500
501static void ddraw_surface_cleanup(struct ddraw_surface *surface)
502{
503 struct ddraw_surface *surf;
504 UINT i;
505
506 TRACE("surface %p.\n", surface);
507
508 /* The refcount test shows that the palette is detached when the surface
509 * is destroyed. */
511
512 /* Loop through all complex attached surfaces and destroy them.
513 *
514 * Yet again, only the root can have more than one complexly attached
515 * surface, all the others have a total of one. */
516 for (i = 0; i < MAX_COMPLEX_ATTACHED; ++i)
517 {
518 if (!surface->complex_array[i])
519 break;
520
521 surf = surface->complex_array[i];
522 surface->complex_array[i] = NULL;
523 if (!surf->is_complex_root)
525 }
526
527 if (surface->device1)
528 IUnknown_Release(&surface->device1->IUnknown_inner);
529
530 if (surface->iface_count > 1)
531 {
532 /* This can happen when a complex surface is destroyed, because the
533 * 2nd surface was addref()ed when the app called
534 * GetAttachedSurface(). */
535 WARN("Destroying surface %p with refcounts 7: %u 4: %u 3: %u 2: %u 1: %u.\n",
536 surface, surface->ref7, surface->ref4, surface->ref3, surface->ref2, surface->ref1);
537 }
538
539 if (surface->wined3d_rtv)
542}
543
545{
547
548 /* Prevent the surface from being destroyed if it's still attached to
549 * another surface. It will be destroyed when the root is destroyed. */
550 if (This->iface_count == 1 && This->attached_iface)
551 IUnknown_AddRef(This->attached_iface);
552 iface_count = InterlockedDecrement(&This->iface_count);
553
554 TRACE("%p decreasing iface count to %u.\n", This, iface_count);
555
556 if (iface_count == 0)
557 {
558 struct ddraw_texture *texture = wined3d_texture_get_parent(This->wined3d_texture);
559 struct wined3d_device *wined3d_device = texture->wined3d_device;
560 IUnknown *release_iface = This->ifaceToRelease;
561
562 /* Complex attached surfaces are destroyed implicitly when the root is released */
564 if(!This->is_complex_root)
565 {
566 WARN("(%p) Attempt to destroy a surface that is not a complex root\n", This);
568 return iface_count;
569 }
572
573 if (release_iface)
574 IUnknown_Release(release_iface);
575 /* Release the device only after anything that may reference it (the
576 * wined3d texture and rendertarget view in particular) is released. */
578 }
579
580 return iface_count;
581}
582
583/*****************************************************************************
584 * IDirectDrawSurface7::Release
585 *
586 * Reduces the surface's refcount by 1. If the refcount falls to 0, the
587 * surface is destroyed.
588 *
589 * Destroying the surface is a bit tricky. For the connection between
590 * WineD3DSurfaces and DirectDrawSurfaces see IDirectDraw7::CreateSurface
591 * It has a nice graph explaining the connection.
592 *
593 * What happens here is basically this:
594 * When a surface is destroyed, its WineD3DSurface is released,
595 * and the refcount of the DirectDraw interface is reduced by 1. If it has
596 * complex surfaces attached to it, then these surfaces are destroyed too,
597 * regardless of their refcount. If any surface being destroyed has another
598 * surface attached to it (with a "soft" attachment, not complex), then
599 * this surface is detached with DeleteAttachedSurface.
600 *
601 * When the surface is a texture, the WineD3DTexture is released.
602 * If the surface is the Direct3D render target, then the D3D
603 * capabilities of the WineD3DDevice are uninitialized, which causes the
604 * swapchain to be released.
605 *
606 * When a complex sublevel falls to ref zero, then this is ignored.
607 *
608 * Returns:
609 * The new refcount
610 *
611 *****************************************************************************/
613{
615 ULONG refcount = InterlockedDecrement(&This->ref7);
616
617 TRACE("iface %p decreasing refcount to %u.\n", iface, refcount);
618
619 if (refcount == 0)
620 {
622 }
623
624 return refcount;
625}
626
627static ULONG WINAPI ddraw_surface4_Release(IDirectDrawSurface4 *iface)
628{
630 ULONG refcount = InterlockedDecrement(&This->ref4);
631
632 TRACE("iface %p decreasing refcount to %u.\n", iface, refcount);
633
634 if (refcount == 0)
635 {
637 }
638
639 return refcount;
640}
641
642static ULONG WINAPI ddraw_surface3_Release(IDirectDrawSurface3 *iface)
643{
645 ULONG refcount = InterlockedDecrement(&This->ref3);
646
647 TRACE("iface %p decreasing refcount to %u.\n", iface, refcount);
648
649 if (refcount == 0)
650 {
652 }
653
654 return refcount;
655}
656
657static ULONG WINAPI ddraw_surface2_Release(IDirectDrawSurface2 *iface)
658{
660 ULONG refcount = InterlockedDecrement(&This->ref2);
661
662 TRACE("iface %p decreasing refcount to %u.\n", iface, refcount);
663
664 if (refcount == 0)
665 {
667 }
668
669 return refcount;
670}
671
672static ULONG WINAPI ddraw_surface1_Release(IDirectDrawSurface *iface)
673{
675 ULONG refcount = InterlockedDecrement(&This->ref1);
676
677 TRACE("iface %p decreasing refcount to %u.\n", iface, refcount);
678
679 if (refcount == 0)
680 {
682 }
683
684 return refcount;
685}
686
687static ULONG WINAPI ddraw_gamma_control_Release(IDirectDrawGammaControl *iface)
688{
690 ULONG refcount = InterlockedDecrement(&This->gamma_count);
691
692 TRACE("iface %p decreasing refcount to %u.\n", iface, refcount);
693
694 if (refcount == 0)
695 {
697 }
698
699 return refcount;
700}
701
702static ULONG WINAPI d3d_texture2_Release(IDirect3DTexture2 *iface)
703{
704 struct ddraw_surface *surface = impl_from_IDirect3DTexture2(iface);
705
706 TRACE("iface %p.\n", iface);
707
708 return IUnknown_Release(surface->texture_outer);
709}
710
711static ULONG WINAPI d3d_texture1_Release(IDirect3DTexture *iface)
712{
713 struct ddraw_surface *surface = impl_from_IDirect3DTexture(iface);
714
715 TRACE("iface %p.\n", iface);
716
717 return IUnknown_Release(surface->texture_outer);
718}
719
720/*****************************************************************************
721 * IDirectDrawSurface7::GetAttachedSurface
722 *
723 * Returns an attached surface with the requested caps. Surface attachment
724 * and complex surfaces are not clearly described by the MSDN or sdk,
725 * so this method is tricky and likely to contain problems.
726 * This implementation searches the complex list first, then the
727 * attachment chain.
728 *
729 * The chains are searched from This down to the last surface in the chain,
730 * not from the first element in the chain. The first surface found is
731 * returned. The MSDN says that this method fails if more than one surface
732 * matches the caps, but it is not sure if that is right. The attachment
733 * structure may not even allow two matching surfaces.
734 *
735 * The found surface is AddRef-ed before it is returned.
736 *
737 * Params:
738 * Caps: Pointer to a DDCAPS2 structure describing the caps asked for
739 * Surface: Address to store the found surface
740 *
741 * Returns:
742 * DD_OK on success
743 * DDERR_INVALIDPARAMS if Caps or Surface is NULL
744 * DDERR_NOTFOUND if no surface was found
745 *
746 *****************************************************************************/
748 DDSCAPS2 *Caps, IDirectDrawSurface7 **Surface)
749{
751 struct ddraw_surface *surf;
752 DDSCAPS2 our_caps;
753 int i;
754
755 TRACE("iface %p, caps %p, attachment %p.\n", iface, Caps, Surface);
756
758
759 if(This->version < 7)
760 {
761 /* Earlier dx apps put garbage into these members, clear them */
762 our_caps.dwCaps = Caps->dwCaps;
763 our_caps.dwCaps2 = 0;
764 our_caps.dwCaps3 = 0;
765 our_caps.u1.dwCaps4 = 0;
766 }
767 else
768 {
769 our_caps = *Caps;
770 }
771
772 TRACE("(%p): Looking for caps: %x,%x,%x,%x\n", This, our_caps.dwCaps, our_caps.dwCaps2, our_caps.dwCaps3, our_caps.u1.dwCaps4); /* FIXME: Better debugging */
773
774 for(i = 0; i < MAX_COMPLEX_ATTACHED; i++)
775 {
776 surf = This->complex_array[i];
777 if(!surf) break;
778
779 TRACE("Surface: (%p) caps: %#x, %#x, %#x, %#x.\n", surf,
783 surf->surface_desc.ddsCaps.u1.dwCaps4);
784
785 if (((surf->surface_desc.ddsCaps.dwCaps & our_caps.dwCaps) == our_caps.dwCaps) &&
786 ((surf->surface_desc.ddsCaps.dwCaps2 & our_caps.dwCaps2) == our_caps.dwCaps2)) {
787
788 /* MSDN: "This method fails if more than one surface is attached
789 * that matches the capabilities requested."
790 *
791 * Not sure how to test this.
792 */
793
794 TRACE("(%p): Returning surface %p\n", This, surf);
795 *Surface = &surf->IDirectDrawSurface7_iface;
796 ddraw_surface7_AddRef(*Surface);
798
799 return DD_OK;
800 }
801 }
802
803 /* Next, look at the attachment chain */
804 surf = This;
805
806 while( (surf = surf->next_attached) )
807 {
808 TRACE("Surface: (%p) caps: %#x, %#x, %#x, %#x.\n", surf,
812 surf->surface_desc.ddsCaps.u1.dwCaps4);
813
814 if (((surf->surface_desc.ddsCaps.dwCaps & our_caps.dwCaps) == our_caps.dwCaps) &&
815 ((surf->surface_desc.ddsCaps.dwCaps2 & our_caps.dwCaps2) == our_caps.dwCaps2)) {
816
817 TRACE("(%p): Returning surface %p\n", This, surf);
818 *Surface = &surf->IDirectDrawSurface7_iface;
819 ddraw_surface7_AddRef(*Surface);
821 return DD_OK;
822 }
823 }
824
825 TRACE("(%p) Didn't find a valid surface\n", This);
826
828
829 *Surface = NULL;
830 return DDERR_NOTFOUND;
831}
832
833static HRESULT WINAPI ddraw_surface4_GetAttachedSurface(IDirectDrawSurface4 *iface,
834 DDSCAPS2 *caps, IDirectDrawSurface4 **attachment)
835{
836 struct ddraw_surface *surface = impl_from_IDirectDrawSurface4(iface);
837 struct ddraw_surface *attachment_impl;
838 IDirectDrawSurface7 *attachment7;
839 HRESULT hr;
840
841 TRACE("iface %p, caps %p, attachment %p.\n", iface, caps, attachment);
842
844 caps, &attachment7);
845 if (FAILED(hr))
846 {
847 *attachment = NULL;
848 return hr;
849 }
850 attachment_impl = impl_from_IDirectDrawSurface7(attachment7);
851 *attachment = &attachment_impl->IDirectDrawSurface4_iface;
853 ddraw_surface7_Release(attachment7);
854
855 return hr;
856}
857
858static HRESULT WINAPI ddraw_surface3_GetAttachedSurface(IDirectDrawSurface3 *iface,
859 DDSCAPS *caps, IDirectDrawSurface3 **attachment)
860{
861 struct ddraw_surface *surface = impl_from_IDirectDrawSurface3(iface);
862 struct ddraw_surface *attachment_impl;
863 IDirectDrawSurface7 *attachment7;
864 DDSCAPS2 caps2;
865 HRESULT hr;
866
867 TRACE("iface %p, caps %p, attachment %p.\n", iface, caps, attachment);
868
869 caps2.dwCaps = caps->dwCaps;
870 caps2.dwCaps2 = 0;
871 caps2.dwCaps3 = 0;
872 caps2.u1.dwCaps4 = 0;
873
875 &caps2, &attachment7);
876 if (FAILED(hr))
877 {
878 *attachment = NULL;
879 return hr;
880 }
881 attachment_impl = impl_from_IDirectDrawSurface7(attachment7);
882 *attachment = &attachment_impl->IDirectDrawSurface3_iface;
884 ddraw_surface7_Release(attachment7);
885
886 return hr;
887}
888
889static HRESULT WINAPI ddraw_surface2_GetAttachedSurface(IDirectDrawSurface2 *iface,
890 DDSCAPS *caps, IDirectDrawSurface2 **attachment)
891{
892 struct ddraw_surface *surface = impl_from_IDirectDrawSurface2(iface);
893 struct ddraw_surface *attachment_impl;
894 IDirectDrawSurface7 *attachment7;
895 DDSCAPS2 caps2;
896 HRESULT hr;
897
898 TRACE("iface %p, caps %p, attachment %p.\n", iface, caps, attachment);
899
900 caps2.dwCaps = caps->dwCaps;
901 caps2.dwCaps2 = 0;
902 caps2.dwCaps3 = 0;
903 caps2.u1.dwCaps4 = 0;
904
906 &caps2, &attachment7);
907 if (FAILED(hr))
908 {
909 *attachment = NULL;
910 return hr;
911 }
912 attachment_impl = impl_from_IDirectDrawSurface7(attachment7);
913 *attachment = &attachment_impl->IDirectDrawSurface2_iface;
915 ddraw_surface7_Release(attachment7);
916
917 return hr;
918}
919
920static HRESULT WINAPI ddraw_surface1_GetAttachedSurface(IDirectDrawSurface *iface,
921 DDSCAPS *caps, IDirectDrawSurface **attachment)
922{
923 struct ddraw_surface *surface = impl_from_IDirectDrawSurface(iface);
924 struct ddraw_surface *attachment_impl;
925 IDirectDrawSurface7 *attachment7;
926 DDSCAPS2 caps2;
927 HRESULT hr;
928
929 TRACE("iface %p, caps %p, attachment %p.\n", iface, caps, attachment);
930
931 caps2.dwCaps = caps->dwCaps;
932 caps2.dwCaps2 = 0;
933 caps2.dwCaps3 = 0;
934 caps2.u1.dwCaps4 = 0;
935
937 &caps2, &attachment7);
938 if (FAILED(hr))
939 {
940 *attachment = NULL;
941 return hr;
942 }
943 attachment_impl = impl_from_IDirectDrawSurface7(attachment7);
944 *attachment = &attachment_impl->IDirectDrawSurface_iface;
946 ddraw_surface7_Release(attachment7);
947
948 return hr;
949}
950
951/*****************************************************************************
952 * IDirectDrawSurface7::Lock
953 *
954 * Locks the surface and returns a pointer to the surface's memory
955 *
956 * Params:
957 * Rect: Rectangle to lock. If NULL, the whole surface is locked
958 * DDSD: Pointer to a DDSURFACEDESC2 which shall receive the surface's desc.
959 * Flags: Locking flags, e.g Read only or write only
960 * h: An event handle that's not used and must be NULL
961 *
962 * Returns:
963 * DD_OK on success
964 * DDERR_INVALIDPARAMS if DDSD is NULL
965 *
966 *****************************************************************************/
967static HRESULT surface_lock(struct ddraw_surface *surface,
968 RECT *rect, DDSURFACEDESC2 *surface_desc, unsigned int surface_desc_size,
970{
971 struct wined3d_map_desc map_desc;
972 struct wined3d_box box;
973 HRESULT hr = DD_OK;
974
975 TRACE("surface %p, rect %s, surface_desc %p, surface_desc_size %u, flags %#x, h %p.\n",
976 surface, wine_dbgstr_rect(rect), surface_desc, surface_desc_size, flags, h);
977
978 /* surface->surface_desc.dwWidth and dwHeight are changeable, thus lock */
980
981 /* Should I check for the handle to be NULL?
982 *
983 * The DDLOCK flags and the D3DLOCK flags are equal
984 * for the supported values. The others are ignored by WineD3D
985 */
986
987 /* Windows zeroes this if the rect is invalid */
988 surface_desc->lpSurface = NULL;
989
990 if (rect)
991 {
992 if ((rect->left < 0) || (rect->top < 0)
993 || (rect->left > rect->right) || (rect->right > surface->surface_desc.dwWidth)
994 || (rect->top > rect->bottom) || (rect->bottom > surface->surface_desc.dwHeight))
995 {
996 WARN("Trying to lock an invalid rectangle, returning DDERR_INVALIDPARAMS\n");
998 return DDERR_INVALIDPARAMS;
999 }
1000 wined3d_box_set(&box, rect->left, rect->top, rect->right, rect->bottom, 0, 1);
1001 }
1002
1005 if (SUCCEEDED(hr))
1007 surface->sub_resource_idx, &map_desc, rect ? &box : NULL,
1009 if (FAILED(hr))
1010 {
1012 switch(hr)
1013 {
1014 /* D3D8 and D3D9 return the general D3DERR_INVALIDCALL error, but ddraw has a more
1015 * specific error. But since wined3d returns that error in this only occasion,
1016 * keep d3d8 and d3d9 free from the return value override. There are many different
1017 * places where d3d8/9 would have to catch the DDERR_SURFACEBUSY, it is much easier
1018 * to do it in one place in ddraw.
1019 */
1021 default: return hr;
1022 }
1023 }
1024
1026 {
1027 if (flags & DDLOCK_READONLY)
1028 SetRectEmpty(&surface->ddraw->primary_lock);
1029 else if (rect)
1030 surface->ddraw->primary_lock = *rect;
1031 else
1032 SetRect(&surface->ddraw->primary_lock, 0, 0, surface->surface_desc.dwWidth, surface->surface_desc.dwHeight);
1033 }
1034
1035 /* Windows does not set DDSD_LPSURFACE on locked surfaces. */
1036 DD_STRUCT_COPY_BYSIZE_(surface_desc, &surface->surface_desc, surface_desc_size, surface->surface_desc.dwSize);
1037 surface_desc->lpSurface = map_desc.data;
1038
1039 TRACE("locked surface returning description :\n");
1040 if (TRACE_ON(ddraw))
1041 DDRAW_dump_surface_desc(surface_desc);
1042
1044
1045 return DD_OK;
1046}
1047
1049 const DDSURFACEDESC *desc, unsigned int *size)
1050{
1051 if (!desc)
1052 return FALSE;
1053
1054 if (desc->dwSize == sizeof(DDSURFACEDESC) || desc->dwSize == sizeof(DDSURFACEDESC2))
1055 {
1056 *size = desc->dwSize;
1057 return TRUE;
1058 }
1059
1060 if (surface->version == 7
1063 {
1064 if (desc->dwSize >= sizeof(DDSURFACEDESC2))
1065 *size = sizeof(DDSURFACEDESC2);
1066 else
1067 *size = sizeof(DDSURFACEDESC);
1068 return TRUE;
1069 }
1070
1071 WARN("Invalid structure size %u.\n", desc->dwSize);
1072 return FALSE;
1073}
1074
1076 RECT *rect, DDSURFACEDESC2 *surface_desc, DWORD flags, HANDLE h)
1077{
1078 struct ddraw_surface *surface = impl_from_IDirectDrawSurface7(iface);
1079 unsigned int surface_desc_size;
1080
1081 TRACE("iface %p, rect %s, surface_desc %p, flags %#x, h %p.\n",
1083
1084 if (!surface_validate_lock_desc(surface, (DDSURFACEDESC *)surface_desc, &surface_desc_size))
1085 return DDERR_INVALIDPARAMS;
1086
1087 return surface_lock(surface, rect, surface_desc, surface_desc_size, flags, h);
1088}
1089
1090static HRESULT WINAPI ddraw_surface4_Lock(IDirectDrawSurface4 *iface, RECT *rect,
1092{
1093 struct ddraw_surface *surface = impl_from_IDirectDrawSurface4(iface);
1094 unsigned int surface_desc_size;
1095
1096 TRACE("iface %p, rect %s, surface_desc %p, flags %#x, h %p.\n",
1098
1099 if (!surface_validate_lock_desc(surface, (DDSURFACEDESC *)surface_desc, &surface_desc_size))
1100 return DDERR_INVALIDPARAMS;
1101
1102 return surface_lock(surface, rect, surface_desc, surface_desc_size, flags, h);
1103}
1104
1105static HRESULT WINAPI ddraw_surface3_Lock(IDirectDrawSurface3 *iface, RECT *rect,
1107{
1108 struct ddraw_surface *surface = impl_from_IDirectDrawSurface3(iface);
1109 unsigned int surface_desc_size;
1110 DDSURFACEDESC2 surface_desc2;
1111 HRESULT hr;
1112
1113 TRACE("iface %p, rect %s, surface_desc %p, flags %#x, h %p.\n",
1115
1116 if (!surface_validate_lock_desc(surface, surface_desc, &surface_desc_size))
1117 return DDERR_INVALIDPARAMS;
1118
1119 surface_desc2.dwSize = surface_desc->dwSize;
1120 surface_desc2.dwFlags = 0;
1121 hr = surface_lock(surface, rect, &surface_desc2, surface_desc_size, flags, h);
1122 DDSD2_to_DDSD(&surface_desc2, surface_desc);
1123 surface_desc->dwSize = surface_desc2.dwSize;
1124 return hr;
1125}
1126
1127static HRESULT WINAPI ddraw_surface2_Lock(IDirectDrawSurface2 *iface, RECT *rect,
1129{
1130 struct ddraw_surface *surface = impl_from_IDirectDrawSurface2(iface);
1131 unsigned int surface_desc_size;
1132 DDSURFACEDESC2 surface_desc2;
1133 HRESULT hr;
1134
1135 TRACE("iface %p, rect %s, surface_desc %p, flags %#x, h %p.\n",
1137
1138 if (!surface_validate_lock_desc(surface, surface_desc, &surface_desc_size))
1139 return DDERR_INVALIDPARAMS;
1140
1141 surface_desc2.dwSize = surface_desc->dwSize;
1142 surface_desc2.dwFlags = 0;
1143 hr = surface_lock(surface, rect, &surface_desc2, surface_desc_size, flags, h);
1144 DDSD2_to_DDSD(&surface_desc2, surface_desc);
1145 surface_desc->dwSize = surface_desc2.dwSize;
1146 return hr;
1147}
1148
1149static HRESULT WINAPI ddraw_surface1_Lock(IDirectDrawSurface *iface, RECT *rect,
1151{
1152 struct ddraw_surface *surface = impl_from_IDirectDrawSurface(iface);
1153 unsigned int surface_desc_size;
1154 DDSURFACEDESC2 surface_desc2;
1155 HRESULT hr;
1156
1157 TRACE("iface %p, rect %s, surface_desc %p, flags %#x, h %p.\n",
1159
1160 if (!surface_validate_lock_desc(surface, surface_desc, &surface_desc_size))
1161 return DDERR_INVALIDPARAMS;
1162
1163 surface_desc2.dwSize = surface_desc->dwSize;
1164 surface_desc2.dwFlags = 0;
1165 hr = surface_lock(surface, rect, &surface_desc2, surface_desc_size, flags, h);
1166 DDSD2_to_DDSD(&surface_desc2, surface_desc);
1167 surface_desc->dwSize = surface_desc2.dwSize;
1168 return hr;
1169}
1170
1171/*****************************************************************************
1172 * IDirectDrawSurface7::Unlock
1173 *
1174 * Unlocks an locked surface
1175 *
1176 * Params:
1177 * Rect: Not used by this implementation
1178 *
1179 * Returns:
1180 * D3D_OK on success, error code otherwise.
1181 *
1182 *****************************************************************************/
1184{
1185 struct ddraw_surface *surface = impl_from_IDirectDrawSurface7(iface);
1186 HRESULT hr;
1187
1188 TRACE("iface %p, rect %s.\n", iface, wine_dbgstr_rect(pRect));
1189
1193 hr = ddraw_surface_update_frontbuffer(surface, &surface->ddraw->primary_lock, FALSE, 0);
1195
1196 return hr;
1197}
1198
1199static HRESULT WINAPI DECLSPEC_HOTPATCH ddraw_surface4_Unlock(IDirectDrawSurface4 *iface, RECT *pRect)
1200{
1201 struct ddraw_surface *surface = impl_from_IDirectDrawSurface4(iface);
1202
1203 TRACE("iface %p, rect %p.\n", iface, pRect);
1204
1205 return ddraw_surface7_Unlock(&surface->IDirectDrawSurface7_iface, pRect);
1206}
1207
1208static HRESULT WINAPI DECLSPEC_HOTPATCH ddraw_surface3_Unlock(IDirectDrawSurface3 *iface, void *data)
1209{
1210 struct ddraw_surface *surface = impl_from_IDirectDrawSurface3(iface);
1211
1212 TRACE("iface %p, data %p.\n", iface, data);
1213
1214 /* data might not be the LPRECT of later versions, so drop it. */
1216}
1217
1218static HRESULT WINAPI DECLSPEC_HOTPATCH ddraw_surface2_Unlock(IDirectDrawSurface2 *iface, void *data)
1219{
1220 struct ddraw_surface *surface = impl_from_IDirectDrawSurface2(iface);
1221
1222 TRACE("iface %p, data %p.\n", iface, data);
1223
1224 /* data might not be the LPRECT of later versions, so drop it. */
1226}
1227
1228static HRESULT WINAPI DECLSPEC_HOTPATCH ddraw_surface1_Unlock(IDirectDrawSurface *iface, void *data)
1229{
1230 struct ddraw_surface *surface = impl_from_IDirectDrawSurface(iface);
1231
1232 TRACE("iface %p, data %p.\n", iface, data);
1233
1234 /* data might not be the LPRECT of later versions, so drop it. */
1236}
1237
1239{
1240 if (flags & DDFLIP_NOVSYNC)
1241 return 0;
1242
1244 {
1245 case DDFLIP_INTERVAL2:
1246 return 2;
1247 case DDFLIP_INTERVAL3:
1248 return 3;
1249 case DDFLIP_INTERVAL4:
1250 return 4;
1251 default:
1252 return 1;
1253 }
1254}
1255
1258{
1259 struct ddraw_surface *dst_impl = impl_from_IDirectDrawSurface7(iface);
1261 struct wined3d_rendertarget_view *tmp_rtv, *src_rtv, *rtv;
1262 struct ddraw_texture *ddraw_texture, *prev_ddraw_texture;
1263 DDSCAPS2 caps = {DDSCAPS_FLIP, 0, 0, {0}};
1264 struct wined3d_texture *texture;
1266 HRESULT hr;
1267
1268 TRACE("iface %p, src %p, flags %#x.\n", iface, src, flags);
1269
1270 if (src == iface || !(dst_impl->surface_desc.ddsCaps.dwCaps & (DDSCAPS_FRONTBUFFER | DDSCAPS_OVERLAY)))
1271 return DDERR_NOTFLIPPABLE;
1272
1273 if (IDirectDrawSurface7_IsLost(iface) == DDERR_SURFACELOST)
1274 return DDERR_SURFACELOST;
1275
1277
1279 && !(dst_impl->ddraw->cooperative_level & DDSCL_EXCLUSIVE))
1280 {
1281 WARN("Not in exclusive mode.\n");
1283 return DDERR_NOEXCLUSIVEMODE;
1284 }
1285
1286 tmp_rtv = ddraw_surface_get_rendertarget_view(dst_impl);
1287 if (dst_impl->sub_resource_idx)
1288 ERR("Invalid sub-resource index %u on surface %p.\n", dst_impl->sub_resource_idx, dst_impl);
1289 texture = dst_impl->wined3d_texture;
1290 rtv = wined3d_device_get_rendertarget_view(dst_impl->ddraw->wined3d_device, 0);
1292
1293 if (src_impl)
1294 {
1295 for (current = iface; current != src;)
1296 {
1298 {
1299 WARN("Surface %p is not on the same flip chain as surface %p.\n", src, iface);
1301 return DDERR_NOTFLIPPABLE;
1302 }
1304 if (current == iface)
1305 {
1306 WARN("Surface %p is not on the same flip chain as surface %p.\n", src, iface);
1308 return DDERR_NOTFLIPPABLE;
1309 }
1310 }
1311
1312 src_rtv = ddraw_surface_get_rendertarget_view(src_impl);
1313 if (rtv == dst_impl->wined3d_rtv)
1314 wined3d_device_set_rendertarget_view(dst_impl->ddraw->wined3d_device, 0, src_rtv, FALSE);
1315 wined3d_rendertarget_view_set_parent(src_rtv, dst_impl);
1316 dst_impl->wined3d_rtv = src_rtv;
1318 prev_ddraw_texture = wined3d_texture_get_parent(src_impl->wined3d_texture);
1320 if (src_impl->sub_resource_idx)
1321 ERR("Invalid sub-resource index %u on surface %p.\n", src_impl->sub_resource_idx, src_impl);
1322 dst_impl->wined3d_texture = src_impl->wined3d_texture;
1323 ddraw_texture = prev_ddraw_texture;
1324 }
1325 else
1326 {
1327 for (current = iface;;)
1328 {
1330 {
1331 ERR("Can't find a flip target\n");
1333 return DDERR_NOTFLIPPABLE; /* Unchecked */
1334 }
1336 if (current == iface)
1337 {
1338 dst_impl = impl_from_IDirectDrawSurface7(iface);
1339 break;
1340 }
1341
1343 src_rtv = ddraw_surface_get_rendertarget_view(src_impl);
1344 if (rtv == dst_impl->wined3d_rtv)
1345 wined3d_device_set_rendertarget_view(dst_impl->ddraw->wined3d_device, 0, src_rtv, FALSE);
1346 wined3d_rendertarget_view_set_parent(src_rtv, dst_impl);
1347 dst_impl->wined3d_rtv = src_rtv;
1349 prev_ddraw_texture = wined3d_texture_get_parent(src_impl->wined3d_texture);
1351 ddraw_texture = prev_ddraw_texture;
1352 if (src_impl->sub_resource_idx)
1353 ERR("Invalid sub-resource index %u on surface %p.\n", src_impl->sub_resource_idx, src_impl);
1354 dst_impl->wined3d_texture = src_impl->wined3d_texture;
1355 dst_impl = src_impl;
1356 }
1357 }
1358
1359 /* We don't have to worry about potential texture bindings, since
1360 * flippable surfaces can never be textures. */
1361 if (rtv == src_impl->wined3d_rtv)
1362 wined3d_device_set_rendertarget_view(dst_impl->ddraw->wined3d_device, 0, tmp_rtv, FALSE);
1363 wined3d_rendertarget_view_set_parent(tmp_rtv, src_impl);
1364 src_impl->wined3d_rtv = tmp_rtv;
1367 src_impl->wined3d_texture = texture;
1368
1369 if (flags)
1370 {
1371 static UINT once;
1372 if (!once++)
1373 FIXME("Ignoring flags %#x.\n", flags);
1374 else
1375 WARN("Ignoring flags %#x.\n", flags);
1376 }
1377
1380 else
1381 hr = DD_OK;
1382
1384
1385 return hr;
1386}
1387
1388static HRESULT WINAPI DECLSPEC_HOTPATCH ddraw_surface4_Flip(IDirectDrawSurface4 *iface,
1389 IDirectDrawSurface4 *src, DWORD flags)
1390{
1391 struct ddraw_surface *surface = impl_from_IDirectDrawSurface4(iface);
1393
1394 TRACE("iface %p, src %p, flags %#x.\n", iface, src, flags);
1395
1397 src_impl ? &src_impl->IDirectDrawSurface7_iface : NULL, flags);
1398}
1399
1400static HRESULT WINAPI DECLSPEC_HOTPATCH ddraw_surface3_Flip(IDirectDrawSurface3 *iface,
1401 IDirectDrawSurface3 *src, DWORD flags)
1402{
1403 struct ddraw_surface *surface = impl_from_IDirectDrawSurface3(iface);
1405
1406 TRACE("iface %p, src %p, flags %#x.\n", iface, src, flags);
1407
1409 src_impl ? &src_impl->IDirectDrawSurface7_iface : NULL, flags);
1410}
1411
1412static HRESULT WINAPI DECLSPEC_HOTPATCH ddraw_surface2_Flip(IDirectDrawSurface2 *iface,
1413 IDirectDrawSurface2 *src, DWORD flags)
1414{
1415 struct ddraw_surface *surface = impl_from_IDirectDrawSurface2(iface);
1417
1418 TRACE("iface %p, src %p, flags %#x.\n", iface, src, flags);
1419
1421 src_impl ? &src_impl->IDirectDrawSurface7_iface : NULL, flags);
1422}
1423
1424static HRESULT WINAPI DECLSPEC_HOTPATCH ddraw_surface1_Flip(IDirectDrawSurface *iface,
1425 IDirectDrawSurface *src, DWORD flags)
1426{
1427 struct ddraw_surface *surface = impl_from_IDirectDrawSurface(iface);
1429
1430 TRACE("iface %p, src %p, flags %#x.\n", iface, src, flags);
1431
1433 src_impl ? &src_impl->IDirectDrawSurface7_iface : NULL, flags);
1434}
1435
1436static HRESULT ddraw_surface_blt(struct ddraw_surface *dst_surface, const RECT *dst_rect,
1437 struct ddraw_surface *src_surface, const RECT *src_rect, DWORD flags, DWORD fill_colour,
1439{
1440 struct wined3d_device *wined3d_device = dst_surface->ddraw->wined3d_device;
1441 struct wined3d_color colour;
1442 DWORD wined3d_flags;
1443
1444 if (flags & DDBLT_COLORFILL)
1445 {
1447 dst_surface->palette, fill_colour, &colour))
1448 return DDERR_INVALIDPARAMS;
1449
1452 dst_rect, WINED3DCLEAR_TARGET, &colour, 0.0f, 0);
1453 }
1454
1455 if (flags & DDBLT_DEPTHFILL)
1456 {
1458 dst_surface->palette, fill_colour, &colour))
1459 return DDERR_INVALIDPARAMS;
1460
1463 dst_rect, WINED3DCLEAR_ZBUFFER, NULL, colour.r, 0);
1464 }
1465
1466 wined3d_flags = flags & ~DDBLT_ASYNC;
1467 if (wined3d_flags & ~WINED3D_BLT_MASK)
1468 {
1469 FIXME("Unhandled flags %#x.\n", flags);
1470 return E_NOTIMPL;
1471 }
1472
1473 if (!(flags & DDBLT_ASYNC))
1474 wined3d_flags |= WINED3D_BLT_SYNCHRONOUS;
1475
1476 return wined3d_texture_blt(dst_surface->wined3d_texture, dst_surface->sub_resource_idx, dst_rect,
1477 src_surface->wined3d_texture, src_surface->sub_resource_idx, src_rect, wined3d_flags, fx, filter);
1478}
1479
1480static HRESULT ddraw_surface_blt_clipped(struct ddraw_surface *dst_surface, const RECT *dst_rect_in,
1481 struct ddraw_surface *src_surface, const RECT *src_rect_in, DWORD flags, DWORD fill_colour,
1483{
1484 RECT src_rect, dst_rect;
1485 float scale_x, scale_y;
1486 const RECT *clip_rect;
1487 UINT clip_list_size;
1488 RGNDATA *clip_list;
1489 HRESULT hr = DD_OK;
1490 UINT i;
1491
1492 if (!dst_rect_in)
1493 SetRect(&dst_rect, 0, 0, dst_surface->surface_desc.dwWidth,
1494 dst_surface->surface_desc.dwHeight);
1495 else
1496 dst_rect = *dst_rect_in;
1497
1498 if (IsRectEmpty(&dst_rect))
1499 return DDERR_INVALIDRECT;
1500
1501 if (src_surface)
1502 {
1503 if (!src_rect_in)
1504 SetRect(&src_rect, 0, 0, src_surface->surface_desc.dwWidth,
1505 src_surface->surface_desc.dwHeight);
1506 else
1507 src_rect = *src_rect_in;
1508
1509 if (IsRectEmpty(&src_rect))
1510 return DDERR_INVALIDRECT;
1511 }
1512 else
1513 {
1514 SetRectEmpty(&src_rect);
1515 }
1516
1517 if (!dst_surface->clipper)
1518 {
1519 if (src_surface && src_surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)
1520 hr = ddraw_surface_update_frontbuffer(src_surface, &src_rect, TRUE, 0);
1521 if (SUCCEEDED(hr))
1522 hr = ddraw_surface_blt(dst_surface, &dst_rect, src_surface, &src_rect, flags, fill_colour, fx, filter);
1524 hr = ddraw_surface_update_frontbuffer(dst_surface, &dst_rect, FALSE, 0);
1525
1526 return hr;
1527 }
1528
1529 scale_x = (float)(src_rect.right - src_rect.left) / (float)(dst_rect.right - dst_rect.left);
1530 scale_y = (float)(src_rect.bottom - src_rect.top) / (float)(dst_rect.bottom - dst_rect.top);
1531
1532 if (FAILED(hr = IDirectDrawClipper_GetClipList(&dst_surface->clipper->IDirectDrawClipper_iface,
1533 &dst_rect, NULL, &clip_list_size)))
1534 {
1535 WARN("Failed to get clip list size, hr %#x.\n", hr);
1536 return hr;
1537 }
1538
1539 if (!(clip_list = heap_alloc(clip_list_size)))
1540 {
1541 WARN("Failed to allocate clip list.\n");
1542 return E_OUTOFMEMORY;
1543 }
1544
1545 if (FAILED(hr = IDirectDrawClipper_GetClipList(&dst_surface->clipper->IDirectDrawClipper_iface,
1546 &dst_rect, clip_list, &clip_list_size)))
1547 {
1548 WARN("Failed to get clip list, hr %#x.\n", hr);
1549 heap_free(clip_list);
1550 return hr;
1551 }
1552
1553 clip_rect = (RECT *)clip_list->Buffer;
1554 for (i = 0; i < clip_list->rdh.nCount; ++i)
1555 {
1556 RECT src_rect_clipped = src_rect;
1557
1558 if (src_surface)
1559 {
1560 src_rect_clipped.left += (LONG)((clip_rect[i].left - dst_rect.left) * scale_x);
1561 src_rect_clipped.top += (LONG)((clip_rect[i].top - dst_rect.top) * scale_y);
1562 src_rect_clipped.right -= (LONG)((dst_rect.right - clip_rect[i].right) * scale_x);
1563 src_rect_clipped.bottom -= (LONG)((dst_rect.bottom - clip_rect[i].bottom) * scale_y);
1564
1566 {
1567 if (FAILED(hr = ddraw_surface_update_frontbuffer(src_surface, &src_rect_clipped, TRUE, 0)))
1568 break;
1569 }
1570 }
1571
1572 if (FAILED(hr = ddraw_surface_blt(dst_surface, &clip_rect[i],
1573 src_surface, &src_rect_clipped, flags, fill_colour, fx, filter)))
1574 break;
1575
1577 {
1578 if (FAILED(hr = ddraw_surface_update_frontbuffer(dst_surface, &clip_rect[i], FALSE, 0)))
1579 break;
1580 }
1581 }
1582
1583 heap_free(clip_list);
1584 return hr;
1585}
1586
1587/*****************************************************************************
1588 * IDirectDrawSurface7::Blt
1589 *
1590 * Performs a blit on the surface
1591 *
1592 * Params:
1593 * DestRect: Destination rectangle, can be NULL
1594 * SrcSurface: Source surface, can be NULL
1595 * SrcRect: Source rectangle, can be NULL
1596 * Flags: Blt flags
1597 * DDBltFx: Some extended blt parameters, connected to the flags
1598 *
1599 * Returns:
1600 * D3D_OK on success, error code otherwise.
1601 *
1602 *****************************************************************************/
1604 IDirectDrawSurface7 *src_surface, RECT *src_rect, DWORD flags, DDBLTFX *fx)
1605{
1606 struct ddraw_surface *dst_impl = impl_from_IDirectDrawSurface7(iface);
1607 struct ddraw_surface *src_impl = unsafe_impl_from_IDirectDrawSurface7(src_surface);
1608 struct wined3d_blt_fx wined3d_fx;
1609 DWORD unsupported_flags;
1610 DWORD fill_colour = 0;
1611 HRESULT hr = DD_OK;
1612 DDBLTFX rop_fx;
1613
1614 TRACE("iface %p, dst_rect %s, src_surface %p, src_rect %s, flags %#x, fx %p.\n",
1615 iface, wine_dbgstr_rect(dst_rect), src_surface, wine_dbgstr_rect(src_rect), flags, fx);
1616
1617 unsupported_flags = DDBLT_ALPHADEST
1631 if (flags & unsupported_flags)
1632 {
1633 WARN("Ignoring unsupported flags %#x.\n", flags & unsupported_flags);
1634 flags &= ~unsupported_flags;
1635 }
1636
1637 if ((flags & DDBLT_KEYSRCOVERRIDE) && (!fx || flags & DDBLT_KEYSRC))
1638 {
1639 WARN("Invalid source color key parameters, returning DDERR_INVALIDPARAMS\n");
1640 return DDERR_INVALIDPARAMS;
1641 }
1642
1644 {
1645 WARN("Invalid destination color key parameters, returning DDERR_INVALIDPARAMS\n");
1646 return DDERR_INVALIDPARAMS;
1647 }
1648
1649 if (flags & DDBLT_DDROPS)
1650 {
1651 FIXME("DDBLT_DDROPS not implemented.\n");
1652 if (fx)
1653 FIXME(" rop %#x, pattern %p.\n", fx->dwDDROP, fx->u5.lpDDSPattern);
1654 return DDERR_NORASTEROPHW;
1655 }
1656
1658
1660 {
1661 if (flags & DDBLT_ROP)
1662 {
1664 WARN("DDBLT_ROP used with DDBLT_COLORFILL or DDBLT_DEPTHFILL, returning DDERR_INVALIDPARAMS.\n");
1665 return DDERR_INVALIDPARAMS;
1666 }
1667 if (src_impl)
1668 {
1670 WARN("Depth or colorfill is not compatible with source surfaces, returning DDERR_INVALIDPARAMS\n");
1671 return DDERR_INVALIDPARAMS;
1672 }
1673 if (!fx)
1674 {
1676 WARN("Depth or colorfill used with NULL fx, returning DDERR_INVALIDPARAMS.\n");
1677 return DDERR_INVALIDPARAMS;
1678 }
1679
1681 flags &= ~DDBLT_DEPTHFILL;
1682
1684 {
1686 WARN("DDBLT_COLORFILL used on a depth buffer, returning DDERR_INVALIDPARAMS.\n");
1687 return DDERR_INVALIDPARAMS;
1688 }
1690 {
1692 WARN("DDBLT_DEPTHFILL used on a color buffer, returning DDERR_INVALIDPARAMS.\n");
1693 return DDERR_INVALIDPARAMS;
1694 }
1695 }
1696
1697 if (flags & DDBLT_ROP)
1698 {
1699 if (!fx)
1700 {
1702 WARN("DDBLT_ROP used with NULL fx, returning DDERR_INVALIDPARAMS.\n");
1703 return DDERR_INVALIDPARAMS;
1704 }
1705
1706 if (src_impl && src_rect
1707 && ((ULONG)src_rect->left >= src_rect->right || src_rect->right > src_impl->surface_desc.dwWidth
1708 || (ULONG)src_rect->top >= src_rect->bottom || src_rect->bottom > src_impl->surface_desc.dwHeight))
1709 {
1710 WARN("Invalid source rectangle.\n");
1711 return DDERR_INVALIDRECT;
1712 }
1713
1714 flags &= ~DDBLT_ROP;
1715 switch (fx->dwROP)
1716 {
1717 case SRCCOPY:
1718 break;
1719
1720 case WHITENESS:
1721 case BLACKNESS:
1722 rop_fx = *fx;
1723
1724 if (fx->dwROP == WHITENESS)
1725 rop_fx.u5.dwFillColor = 0xffffffff;
1726 else
1727 rop_fx.u5.dwFillColor = 0;
1728
1731 else
1733
1734 fx = &rop_fx;
1735 break;
1736
1737 default:
1739 WARN("Unsupported ROP %#x used, returning DDERR_NORASTEROPHW.\n", fx->dwROP);
1740 return DDERR_NORASTEROPHW;
1741 }
1742 }
1743
1744 if (!(flags & (DDBLT_COLORFILL | DDBLT_DEPTHFILL)) && !src_impl)
1745 {
1746 WARN("No source surface.\n");
1747 return DDERR_INVALIDPARAMS;
1748 }
1749
1750 if (flags & DDBLT_KEYSRC && (!src_impl || !(src_impl->surface_desc.dwFlags & DDSD_CKSRCBLT)))
1751 {
1752 WARN("DDBLT_KEYSRC blit without color key in surface, returning DDERR_INVALIDPARAMS\n");
1754 return DDERR_INVALIDPARAMS;
1755 }
1756 if (flags & DDBLT_KEYDEST && !(dst_impl->surface_desc.dwFlags & DDSD_CKDESTBLT))
1757 {
1758 WARN("DDBLT_KEYDEST blit without color key in surface, returning DDERR_INVALIDPARAMS\n");
1760 return DDERR_INVALIDPARAMS;
1761 }
1762
1763 if (fx)
1764 {
1765 wined3d_fx.fx = fx->dwDDFX;
1766 fill_colour = fx->u5.dwFillColor;
1767 wined3d_fx.dst_color_key.color_space_low_value = fx->ddckDestColorkey.dwColorSpaceLowValue;
1768 wined3d_fx.dst_color_key.color_space_high_value = fx->ddckDestColorkey.dwColorSpaceHighValue;
1769 wined3d_fx.src_color_key.color_space_low_value = fx->ddckSrcColorkey.dwColorSpaceLowValue;
1770 wined3d_fx.src_color_key.color_space_high_value = fx->ddckSrcColorkey.dwColorSpaceHighValue;
1771 }
1772
1773 hr = ddraw_surface_blt_clipped(dst_impl, dst_rect, src_impl,
1774 src_rect, flags, fill_colour, fx ? &wined3d_fx : NULL, WINED3D_TEXF_LINEAR);
1775
1777 switch(hr)
1778 {
1780 default: return hr;
1781 }
1782}
1783
1784static HRESULT WINAPI DECLSPEC_HOTPATCH ddraw_surface4_Blt(IDirectDrawSurface4 *iface, RECT *dst_rect,
1785 IDirectDrawSurface4 *src_surface, RECT *src_rect, DWORD flags, DDBLTFX *fx)
1786{
1789
1790 TRACE("iface %p, dst_rect %s, src_surface %p, src_rect %s, flags %#x, fx %p.\n",
1791 iface, wine_dbgstr_rect(dst_rect), src_surface, wine_dbgstr_rect(src_rect), flags, fx);
1792
1793 return ddraw_surface7_Blt(&dst->IDirectDrawSurface7_iface, dst_rect,
1794 src ? &src->IDirectDrawSurface7_iface : NULL, src_rect, flags, fx);
1795}
1796
1797static HRESULT WINAPI DECLSPEC_HOTPATCH ddraw_surface3_Blt(IDirectDrawSurface3 *iface, RECT *dst_rect,
1798 IDirectDrawSurface3 *src_surface, RECT *src_rect, DWORD flags, DDBLTFX *fx)
1799{
1801 struct ddraw_surface *src_impl = unsafe_impl_from_IDirectDrawSurface3(src_surface);
1802
1803 TRACE("iface %p, dst_rect %s, src_surface %p, src_rect %s, flags %#x, fx %p.\n",
1804 iface, wine_dbgstr_rect(dst_rect), src_surface, wine_dbgstr_rect(src_rect), flags, fx);
1805
1806 return ddraw_surface7_Blt(&dst->IDirectDrawSurface7_iface, dst_rect,
1807 src_impl ? &src_impl->IDirectDrawSurface7_iface : NULL, src_rect, flags, fx);
1808}
1809
1810static HRESULT WINAPI DECLSPEC_HOTPATCH ddraw_surface2_Blt(IDirectDrawSurface2 *iface, RECT *dst_rect,
1811 IDirectDrawSurface2 *src_surface, RECT *src_rect, DWORD flags, DDBLTFX *fx)
1812{
1814 struct ddraw_surface *src_impl = unsafe_impl_from_IDirectDrawSurface2(src_surface);
1815
1816 TRACE("iface %p, dst_rect %s, src_surface %p, src_rect %s, flags %#x, fx %p.\n",
1817 iface, wine_dbgstr_rect(dst_rect), src_surface, wine_dbgstr_rect(src_rect), flags, fx);
1818
1819 return ddraw_surface7_Blt(&dst->IDirectDrawSurface7_iface, dst_rect,
1820 src_impl ? &src_impl->IDirectDrawSurface7_iface : NULL, src_rect, flags, fx);
1821}
1822
1823static HRESULT WINAPI DECLSPEC_HOTPATCH ddraw_surface1_Blt(IDirectDrawSurface *iface, RECT *dst_rect,
1824 IDirectDrawSurface *src_surface, RECT *src_rect, DWORD flags, DDBLTFX *fx)
1825{
1827 struct ddraw_surface *src_impl = unsafe_impl_from_IDirectDrawSurface(src_surface);
1828
1829 TRACE("iface %p, dst_rect %s, src_surface %p, src_rect %s, flags %#x, fx %p.\n",
1830 iface, wine_dbgstr_rect(dst_rect), src_surface, wine_dbgstr_rect(src_rect), flags, fx);
1831
1832 return ddraw_surface7_Blt(&dst->IDirectDrawSurface7_iface, dst_rect,
1833 src_impl ? &src_impl->IDirectDrawSurface7_iface : NULL, src_rect, flags, fx);
1834}
1835
1836/*****************************************************************************
1837 * IDirectDrawSurface7::AddAttachedSurface
1838 *
1839 * Attaches a surface to another surface. How the surface attachments work
1840 * is not totally understood yet, and this method is prone to problems.
1841 * The surface that is attached is AddRef-ed.
1842 *
1843 * Tests with complex surfaces suggest that the surface attachments form a
1844 * tree, but no method to test this has been found yet.
1845 *
1846 * The attachment list consists of a first surface (first_attached) and
1847 * for each surface a pointer to the next attached surface (next_attached).
1848 * For the first surface, and a surface that has no attachments
1849 * first_attached points to the surface itself. A surface that has
1850 * no successors in the chain has next_attached set to NULL.
1851 *
1852 * Newly attached surfaces are attached right after the root surface.
1853 * If a surface is attached to a complex surface compound, it's attached to
1854 * the surface that the app requested, not the complex root. See
1855 * GetAttachedSurface for a description how surfaces are found.
1856 *
1857 * This is how the current implementation works, and it was coded by looking
1858 * at the needs of the applications.
1859 *
1860 * So far only Z-Buffer attachments are tested, and they are activated in
1861 * WineD3D. Mipmaps could be tricky to activate in WineD3D.
1862 * Back buffers should work in 2D mode, but they are not tested(They can be
1863 * attached in older iface versions). Rendering to the front buffer and
1864 * switching between that and double buffering is not yet implemented in
1865 * WineD3D, so for 3D it might have unexpected results.
1866 *
1867 * ddraw_surface_attach_surface is the real thing,
1868 * ddraw_surface7_AddAttachedSurface is a wrapper around it that
1869 * performs additional checks. Version 7 of this interface is much more restrictive
1870 * than its predecessors.
1871 *
1872 * Params:
1873 * Attach: Surface to attach to iface
1874 *
1875 * Returns:
1876 * DD_OK on success
1877 * DDERR_CANNOTATTACHSURFACE if the surface can't be attached for some reason
1878 *
1879 *****************************************************************************/
1881{
1882 TRACE("surface %p, attachment %p.\n", This, Surf);
1883
1884 if(Surf == This)
1885 return DDERR_CANNOTATTACHSURFACE; /* unchecked */
1886
1888
1889 /* Check if the surface is already attached somewhere */
1890 if (Surf->next_attached || Surf->first_attached != Surf)
1891 {
1892 /* TODO: Test for the structure of the manual attachment. Is it a
1893 * chain or a list? What happens if one surface is attached to 2
1894 * different surfaces? */
1895 WARN("Surface %p is already attached somewhere. next_attached %p, first_attached %p.\n",
1896 Surf, Surf->next_attached, Surf->first_attached);
1897
1900 }
1901
1902 /* This inserts the new surface at the 2nd position in the chain, right after the root surface */
1903 Surf->next_attached = This->next_attached;
1904 Surf->first_attached = This->first_attached;
1905 This->next_attached = Surf;
1906
1907 /* Check if the WineD3D depth stencil needs updating */
1908 if (This->ddraw->d3ddevice)
1909 d3d_device_update_depth_stencil(This->ddraw->d3ddevice);
1910
1912
1913 return DD_OK;
1914}
1915
1917{
1920 HRESULT hr;
1921
1922 TRACE("iface %p, attachment %p.\n", iface, attachment);
1923
1924 /* Version 7 of this interface seems to refuse everything except z buffers, as per msdn */
1925 if(!(attachment_impl->surface_desc.ddsCaps.dwCaps & DDSCAPS_ZBUFFER))
1926 {
1927
1928 WARN("Application tries to attach a non Z buffer surface. caps %08x\n",
1929 attachment_impl->surface_desc.ddsCaps.dwCaps);
1931 }
1932
1933 hr = ddraw_surface_attach_surface(This, attachment_impl);
1934 if (FAILED(hr))
1935 {
1936 return hr;
1937 }
1938 attachment_impl->attached_iface = (IUnknown *)attachment;
1939 IUnknown_AddRef(attachment_impl->attached_iface);
1940 return hr;
1941}
1942
1943static HRESULT WINAPI ddraw_surface4_AddAttachedSurface(IDirectDrawSurface4 *iface, IDirectDrawSurface4 *attachment)
1944{
1945 struct ddraw_surface *surface = impl_from_IDirectDrawSurface4(iface);
1947 HRESULT hr;
1948
1949 TRACE("iface %p, attachment %p.\n", iface, attachment);
1950
1951 /* Tests suggest that
1952 * -> offscreen plain surfaces can be attached to other offscreen plain surfaces
1953 * -> offscreen plain surfaces can be attached to primaries
1954 * -> primaries can be attached to offscreen plain surfaces
1955 * -> z buffers can be attached to primaries */
1958 {
1959 /* Sizes have to match */
1960 if (attachment_impl->surface_desc.dwWidth != surface->surface_desc.dwWidth
1961 || attachment_impl->surface_desc.dwHeight != surface->surface_desc.dwHeight)
1962 {
1963 WARN("Surface sizes do not match.\n");
1965 }
1966 }
1968 || !(attachment_impl->surface_desc.ddsCaps.dwCaps & (DDSCAPS_ZBUFFER)))
1969 {
1970 WARN("Invalid attachment combination.\n");
1972 }
1973
1974 if (FAILED(hr = ddraw_surface_attach_surface(surface, attachment_impl)))
1975 return hr;
1976
1977 attachment_impl->attached_iface = (IUnknown *)attachment;
1978 IUnknown_AddRef(attachment_impl->attached_iface);
1979 return hr;
1980}
1981
1982static HRESULT WINAPI ddraw_surface3_AddAttachedSurface(IDirectDrawSurface3 *iface, IDirectDrawSurface3 *attachment)
1983{
1984 struct ddraw_surface *surface = impl_from_IDirectDrawSurface3(iface);
1986 HRESULT hr;
1987
1988 TRACE("iface %p, attachment %p.\n", iface, attachment);
1989
1991 attachment_impl ? &attachment_impl->IDirectDrawSurface4_iface : NULL)))
1992 return hr;
1993
1994 attachment_impl->attached_iface = (IUnknown *)attachment;
1995 IUnknown_AddRef(attachment_impl->attached_iface);
1997 return hr;
1998}
1999
2000static HRESULT WINAPI ddraw_surface2_AddAttachedSurface(IDirectDrawSurface2 *iface, IDirectDrawSurface2 *attachment)
2001{
2002 struct ddraw_surface *surface = impl_from_IDirectDrawSurface2(iface);
2004 HRESULT hr;
2005
2006 TRACE("iface %p, attachment %p.\n", iface, attachment);
2007
2009 attachment_impl ? &attachment_impl->IDirectDrawSurface4_iface : NULL)))
2010 return hr;
2011
2012 attachment_impl->attached_iface = (IUnknown *)attachment;
2013 IUnknown_AddRef(attachment_impl->attached_iface);
2015 return hr;
2016}
2017
2018static HRESULT WINAPI ddraw_surface1_AddAttachedSurface(IDirectDrawSurface *iface, IDirectDrawSurface *attachment)
2019{
2020 struct ddraw_surface *surface = impl_from_IDirectDrawSurface(iface);
2022 HRESULT hr;
2023
2024 TRACE("iface %p, attachment %p.\n", iface, attachment);
2025
2027 attachment_impl ? &attachment_impl->IDirectDrawSurface4_iface : NULL)))
2028 return hr;
2029
2030 attachment_impl->attached_iface = (IUnknown *)attachment;
2031 IUnknown_AddRef(attachment_impl->attached_iface);
2033 return hr;
2034}
2035
2036/*****************************************************************************
2037 * IDirectDrawSurface7::DeleteAttachedSurface
2038 *
2039 * Removes a surface from the attachment chain. The surface's refcount
2040 * is decreased by one after it has been removed
2041 *
2042 * Params:
2043 * Flags: Some flags, not used by this implementation
2044 * Attach: Surface to detach
2045 *
2046 * Returns:
2047 * DD_OK on success
2048 * DDERR_SURFACENOTATTACHED if the surface isn't attached to
2049 *
2050 *****************************************************************************/
2052 struct ddraw_surface *attachment, IUnknown *detach_iface)
2053{
2054 struct ddraw_surface *prev = surface;
2055
2056 TRACE("surface %p, attachment %p, detach_iface %p.\n", surface, attachment, detach_iface);
2057
2059 if (!attachment || (attachment->first_attached != surface) || (attachment == surface) )
2060 {
2063 }
2064
2065 if (attachment->attached_iface != detach_iface)
2066 {
2067 WARN("attachment->attach_iface %p != detach_iface %p.\n", attachment->attached_iface, detach_iface);
2070 }
2071
2072 /* Remove MIPMAPSUBLEVEL if this seemed to be one */
2073 if (surface->surface_desc.ddsCaps.dwCaps & attachment->surface_desc.ddsCaps.dwCaps & DDSCAPS_MIPMAP)
2074 {
2075 attachment->surface_desc.ddsCaps.dwCaps2 &= ~DDSCAPS2_MIPMAPSUBLEVEL;
2076 /* FIXME: we should probably also subtract from dwMipMapCount of this
2077 * and all parent surfaces */
2078 }
2079
2080 /* Find the predecessor of the detached surface */
2081 while (prev->next_attached != attachment)
2082 {
2083 if (!(prev = prev->next_attached))
2084 {
2085 ERR("Failed to find predecessor of %p.\n", attachment);
2088 }
2089 }
2090
2091 /* Unchain the surface */
2092 prev->next_attached = attachment->next_attached;
2093 attachment->next_attached = NULL;
2094 attachment->first_attached = attachment;
2095
2096 /* Check if the wined3d depth stencil needs updating. Note that we don't
2097 * just call d3d_device_update_depth_stencil() here since it uses
2098 * QueryInterface(). Some applications, SCP - Containment Breach in
2099 * particular, modify the QueryInterface() pointer in the surface vtbl
2100 * but don't cleanup properly after the relevant dll is unloaded. */
2101 if (attachment->surface_desc.ddsCaps.dwCaps & DDSCAPS_ZBUFFER
2102 && wined3d_device_get_depth_stencil_view(surface->ddraw->wined3d_device) == attachment->wined3d_rtv)
2103 wined3d_device_set_depth_stencil_view(surface->ddraw->wined3d_device, NULL);
2105
2106 /* Set attached_iface to NULL before releasing it, the surface may go
2107 * away. */
2108 attachment->attached_iface = NULL;
2109 IUnknown_Release(detach_iface);
2110
2111 return DD_OK;
2112}
2113
2116{
2117 struct ddraw_surface *surface = impl_from_IDirectDrawSurface7(iface);
2119
2120 TRACE("iface %p, flags %#x, attachment %p.\n", iface, flags, attachment);
2121
2122 return ddraw_surface_delete_attached_surface(surface, attachment_impl, (IUnknown *)attachment);
2123}
2124
2125static HRESULT WINAPI ddraw_surface4_DeleteAttachedSurface(IDirectDrawSurface4 *iface,
2126 DWORD flags, IDirectDrawSurface4 *attachment)
2127{
2128 struct ddraw_surface *surface = impl_from_IDirectDrawSurface4(iface);
2130
2131 TRACE("iface %p, flags %#x, attachment %p.\n", iface, flags, attachment);
2132
2133 return ddraw_surface_delete_attached_surface(surface, attachment_impl, (IUnknown *)attachment);
2134}
2135
2136static HRESULT WINAPI ddraw_surface3_DeleteAttachedSurface(IDirectDrawSurface3 *iface,
2137 DWORD flags, IDirectDrawSurface3 *attachment)
2138{
2139 struct ddraw_surface *surface = impl_from_IDirectDrawSurface3(iface);
2141
2142 TRACE("iface %p, flags %#x, attachment %p.\n", iface, flags, attachment);
2143
2144 return ddraw_surface_delete_attached_surface(surface, attachment_impl, (IUnknown *)attachment);
2145}
2146
2147static HRESULT WINAPI ddraw_surface2_DeleteAttachedSurface(IDirectDrawSurface2 *iface,
2148 DWORD flags, IDirectDrawSurface2 *attachment)
2149{
2150 struct ddraw_surface *surface = impl_from_IDirectDrawSurface2(iface);
2152
2153 TRACE("iface %p, flags %#x, attachment %p.\n", iface, flags, attachment);
2154
2155 return ddraw_surface_delete_attached_surface(surface, attachment_impl, (IUnknown *)attachment);
2156}
2157
2158static HRESULT WINAPI ddraw_surface1_DeleteAttachedSurface(IDirectDrawSurface *iface,
2159 DWORD flags, IDirectDrawSurface *attachment)
2160{
2161 struct ddraw_surface *surface = impl_from_IDirectDrawSurface(iface);
2163
2164 TRACE("iface %p, flags %#x, attachment %p.\n", iface, flags, attachment);
2165
2166 return ddraw_surface_delete_attached_surface(surface, attachment_impl, (IUnknown *)attachment);
2167}
2168
2169/*****************************************************************************
2170 * IDirectDrawSurface7::AddOverlayDirtyRect
2171 *
2172 * "This method is not currently implemented"
2173 *
2174 * Params:
2175 * Rect: ?
2176 *
2177 * Returns:
2178 * DDERR_UNSUPPORTED
2179 *
2180 *****************************************************************************/
2182{
2183 TRACE("iface %p, rect %s.\n", iface, wine_dbgstr_rect(Rect));
2184
2185 return DDERR_UNSUPPORTED; /* unchecked */
2186}
2187
2188static HRESULT WINAPI ddraw_surface4_AddOverlayDirtyRect(IDirectDrawSurface4 *iface, RECT *rect)
2189{
2190 struct ddraw_surface *surface = impl_from_IDirectDrawSurface4(iface);
2191
2192 TRACE("iface %p, rect %s.\n", iface, wine_dbgstr_rect(rect));
2193
2195}
2196
2197static HRESULT WINAPI ddraw_surface3_AddOverlayDirtyRect(IDirectDrawSurface3 *iface, RECT *rect)
2198{
2199 struct ddraw_surface *surface = impl_from_IDirectDrawSurface3(iface);
2200
2201 TRACE("iface %p, rect %s.\n", iface, wine_dbgstr_rect(rect));
2202
2204}
2205
2206static HRESULT WINAPI ddraw_surface2_AddOverlayDirtyRect(IDirectDrawSurface2 *iface, RECT *rect)
2207{
2208 struct ddraw_surface *surface = impl_from_IDirectDrawSurface2(iface);
2209
2210 TRACE("iface %p, rect %s.\n", iface, wine_dbgstr_rect(rect));
2211
2213}
2214
2215static HRESULT WINAPI ddraw_surface1_AddOverlayDirtyRect(IDirectDrawSurface *iface, RECT *rect)
2216{
2217 struct ddraw_surface *surface = impl_from_IDirectDrawSurface(iface);
2218
2219 TRACE("iface %p, rect %s.\n", iface, wine_dbgstr_rect(rect));
2220
2222}
2223
2224/*****************************************************************************
2225 * IDirectDrawSurface7::GetDC
2226 *
2227 * Returns a GDI device context for the surface
2228 *
2229 * Params:
2230 * hdc: Address of a HDC variable to store the dc to
2231 *
2232 * Returns:
2233 * DD_OK on success
2234 * DDERR_INVALIDPARAMS if hdc is NULL
2235 *
2236 *****************************************************************************/
2238{
2239 struct ddraw_surface *surface = impl_from_IDirectDrawSurface7(iface);
2240 HRESULT hr = DD_OK;
2241
2242 TRACE("iface %p, dc %p.\n", iface, dc);
2243
2244 if (!dc)
2245 return DDERR_INVALIDPARAMS;
2246
2248 if (surface->dc)
2252 if (SUCCEEDED(hr))
2254
2255 if (SUCCEEDED(hr))
2256 {
2257 surface->dc = *dc;
2258
2260 {
2261 const struct ddraw_palette *palette;
2262
2263 if (surface->palette)
2264 palette = surface->palette;
2265 else if (surface->ddraw->primary)
2266 palette = surface->ddraw->primary->palette;
2267 else
2268 palette = NULL;
2269
2270 if (palette)
2271 wined3d_palette_apply_to_dc(palette->wined3d_palette, *dc);
2272 }
2273 }
2274
2276 switch (hr)
2277 {
2278 /* Some, but not all errors set *dc to NULL. E.g. DCALREADYCREATED
2279 * does not touch *dc. */
2281 *dc = NULL;
2282 return DDERR_CANTCREATEDC;
2283
2284 default:
2285 return hr;
2286 }
2287}
2288
2289static HRESULT WINAPI ddraw_surface4_GetDC(IDirectDrawSurface4 *iface, HDC *dc)
2290{
2291 struct ddraw_surface *surface = impl_from_IDirectDrawSurface4(iface);
2292
2293 TRACE("iface %p, dc %p.\n", iface, dc);
2294
2296}
2297
2298static HRESULT WINAPI ddraw_surface3_GetDC(IDirectDrawSurface3 *iface, HDC *dc)
2299{
2300 struct ddraw_surface *surface = impl_from_IDirectDrawSurface3(iface);
2301
2302 TRACE("iface %p, dc %p.\n", iface, dc);
2303
2305}
2306
2307static HRESULT WINAPI ddraw_surface2_GetDC(IDirectDrawSurface2 *iface, HDC *dc)
2308{
2309 struct ddraw_surface *surface = impl_from_IDirectDrawSurface2(iface);
2310
2311 TRACE("iface %p, dc %p.\n", iface, dc);
2312
2314}
2315
2316static HRESULT WINAPI ddraw_surface1_GetDC(IDirectDrawSurface *iface, HDC *dc)
2317{
2318 struct ddraw_surface *surface = impl_from_IDirectDrawSurface(iface);
2319
2320 TRACE("iface %p, dc %p.\n", iface, dc);
2321
2323}
2324
2325/*****************************************************************************
2326 * IDirectDrawSurface7::ReleaseDC
2327 *
2328 * Releases the DC that was constructed with GetDC
2329 *
2330 * Params:
2331 * hdc: HDC to release
2332 *
2333 * Returns:
2334 * DD_OK on success, error code otherwise.
2335 *
2336 *****************************************************************************/
2338{
2339 struct ddraw_surface *surface = impl_from_IDirectDrawSurface7(iface);
2340 HRESULT hr;
2341
2342 TRACE("iface %p, dc %p.\n", iface, hdc);
2343#ifdef __REACTOS__
2344 GdiFlush();
2345#endif
2347 if (!surface->dc)
2348 {
2349 hr = DDERR_NODC;
2350 }
2352 {
2353 surface->dc = NULL;
2356 }
2358
2359
2360 return hr;
2361}
2362
2363static HRESULT WINAPI ddraw_surface4_ReleaseDC(IDirectDrawSurface4 *iface, HDC dc)
2364{
2365 struct ddraw_surface *surface = impl_from_IDirectDrawSurface4(iface);
2366
2367 TRACE("iface %p, dc %p.\n", iface, dc);
2368
2370}
2371
2372static HRESULT WINAPI ddraw_surface3_ReleaseDC(IDirectDrawSurface3 *iface, HDC dc)
2373{
2374 struct ddraw_surface *surface = impl_from_IDirectDrawSurface3(iface);
2375
2376 TRACE("iface %p, dc %p.\n", iface, dc);
2377
2379}
2380
2381static HRESULT WINAPI ddraw_surface2_ReleaseDC(IDirectDrawSurface2 *iface, HDC dc)
2382{
2383 struct ddraw_surface *surface = impl_from_IDirectDrawSurface2(iface);
2384
2385 TRACE("iface %p, dc %p.\n", iface, dc);
2386
2388}
2389
2390static HRESULT WINAPI ddraw_surface1_ReleaseDC(IDirectDrawSurface *iface, HDC dc)
2391{
2392 struct ddraw_surface *surface = impl_from_IDirectDrawSurface(iface);
2393
2394 TRACE("iface %p, dc %p.\n", iface, dc);
2395
2397}
2398
2399/*****************************************************************************
2400 * IDirectDrawSurface7::GetCaps
2401 *
2402 * Returns the surface's caps
2403 *
2404 * Params:
2405 * Caps: Address to write the caps to
2406 *
2407 * Returns:
2408 * DD_OK on success
2409 * DDERR_INVALIDPARAMS if Caps is NULL
2410 *
2411 *****************************************************************************/
2413{
2414 struct ddraw_surface *surface = impl_from_IDirectDrawSurface7(iface);
2415
2416 TRACE("iface %p, caps %p.\n", iface, Caps);
2417
2418 if(!Caps)
2419 return DDERR_INVALIDPARAMS;
2420
2421 *Caps = surface->surface_desc.ddsCaps;
2422
2423 return DD_OK;
2424}
2425
2426static HRESULT WINAPI ddraw_surface4_GetCaps(IDirectDrawSurface4 *iface, DDSCAPS2 *caps)
2427{
2428 struct ddraw_surface *surface = impl_from_IDirectDrawSurface4(iface);
2429
2430 TRACE("iface %p, caps %p.\n", iface, caps);
2431
2432 return ddraw_surface7_GetCaps(&surface->IDirectDrawSurface7_iface, caps);
2433}
2434
2435static HRESULT WINAPI ddraw_surface3_GetCaps(IDirectDrawSurface3 *iface, DDSCAPS *caps)
2436{
2437 struct ddraw_surface *surface = impl_from_IDirectDrawSurface3(iface);
2438 DDSCAPS2 caps2;
2439 HRESULT hr;
2440
2441 TRACE("iface %p, caps %p.\n", iface, caps);
2442
2444 if (FAILED(hr)) return hr;
2445
2446 caps->dwCaps = caps2.dwCaps;
2447 return hr;
2448}
2449
2450static HRESULT WINAPI ddraw_surface2_GetCaps(IDirectDrawSurface2 *iface, DDSCAPS *caps)
2451{
2452 struct ddraw_surface *surface = impl_from_IDirectDrawSurface2(iface);
2453 DDSCAPS2 caps2;
2454 HRESULT hr;
2455
2456 TRACE("iface %p, caps %p.\n", iface, caps);
2457
2459 if (FAILED(hr)) return hr;
2460
2461 caps->dwCaps = caps2.dwCaps;
2462 return hr;
2463}
2464
2465static HRESULT WINAPI ddraw_surface1_GetCaps(IDirectDrawSurface *iface, DDSCAPS *caps)
2466{
2467 struct ddraw_surface *surface = impl_from_IDirectDrawSurface(iface);
2468 DDSCAPS2 caps2;
2469 HRESULT hr;
2470
2471 TRACE("iface %p, caps %p.\n", iface, caps);
2472
2474 if (FAILED(hr)) return hr;
2475
2476 caps->dwCaps = caps2.dwCaps;
2477 return hr;
2478}
2479
2481{
2482 struct ddraw_surface *surface = impl_from_IDirectDrawSurface7(iface);
2484 HRESULT hr;
2485 struct wined3d_resource *resource;
2486
2487 TRACE("iface %p, priority %u.\n", iface, priority);
2488
2490 /* No need to check for offscreen plain surfaces or mipmap sublevels. SetPriority
2491 * calls on such surfaces segfault on Windows. */
2492 if (!(surface->surface_desc.ddsCaps.dwCaps2 & managed))
2493 {
2494 WARN("Called on non-managed texture returning DDERR_INVALIDPARAMS.\n");
2496 }
2497 else
2498 {
2501 hr = DD_OK;
2502 }
2504
2505 return hr;
2506}
2507
2509{
2510 struct ddraw_surface *surface = impl_from_IDirectDrawSurface7(iface);
2511 const struct wined3d_resource *resource;
2513 HRESULT hr;
2514
2515 TRACE("iface %p, priority %p.\n", iface, priority);
2516
2519 {
2520 WARN("Called on offscreenplain surface, returning DDERR_INVALIDOBJECT.\n");
2522 }
2523 else if (!(surface->surface_desc.ddsCaps.dwCaps2 & managed) || !surface->is_complex_root)
2524 {
2525 WARN("Called on non-managed texture or non-root surface, returning DDERR_INVALIDPARAMS.\n");
2527 }
2528 else
2529 {
2532 hr = DD_OK;
2533 }
2535
2536 return hr;
2537}
2538
2539/*****************************************************************************
2540 * IDirectDrawSurface7::SetPrivateData
2541 *
2542 * Stores some data in the surface that is intended for the application's
2543 * use.
2544 *
2545 * Params:
2546 * tag: GUID that identifies the data
2547 * Data: Pointer to the private data
2548 * Size: Size of the private data
2549 * Flags: Some flags
2550 *
2551 * Returns:
2552 * D3D_OK on success, error code otherwise.
2553 *
2554 *****************************************************************************/
2556 REFGUID tag, void *data, DWORD size, DWORD flags)
2557{
2558 struct ddraw_surface *surface = impl_from_IDirectDrawSurface7(iface);
2559 HRESULT hr;
2560
2561 TRACE("iface %p, tag %s, data %p, data_size %u, flags %#x.\n",
2562 iface, debugstr_guid(tag), data, size, flags);
2563
2564 if (!data)
2565 {
2566 WARN("data is NULL, returning DDERR_INVALIDPARAMS.\n");
2567 return DDERR_INVALIDPARAMS;
2568 }
2569
2573 return hr_ddraw_from_wined3d(hr);
2574}
2575
2576static HRESULT WINAPI ddraw_surface4_SetPrivateData(IDirectDrawSurface4 *iface,
2577 REFGUID tag, void *data, DWORD size, DWORD flags)
2578{
2579 struct ddraw_surface *surface = impl_from_IDirectDrawSurface4(iface);
2580
2581 TRACE("iface %p, tag %s, data %p, data_size %u, flags %#x.\n",
2582 iface, debugstr_guid(tag), data, size, flags);
2583
2585}
2586
2587/*****************************************************************************
2588 * IDirectDrawSurface7::GetPrivateData
2589 *
2590 * Returns the private data set with IDirectDrawSurface7::SetPrivateData
2591 *
2592 * Params:
2593 * tag: GUID of the data to return
2594 * Data: Address where to write the data to
2595 * Size: Size of the buffer at Data
2596 *
2597 * Returns:
2598 * DD_OK on success
2599 * DDERR_INVALIDPARAMS if Data is NULL
2600 *
2601 *****************************************************************************/
2603{
2604 struct ddraw_surface *surface = impl_from_IDirectDrawSurface7(iface);
2605 const struct wined3d_private_data *stored_data;
2606 HRESULT hr;
2607
2608 TRACE("iface %p, tag %s, data %p, data_size %p.\n",
2609 iface, debugstr_guid(tag), data, size);
2610
2613 if (!stored_data)
2614 {
2616 goto done;
2617 }
2618 if (!size)
2619 {
2621 goto done;
2622 }
2623 if (*size < stored_data->size)
2624 {
2625 *size = stored_data->size;
2627 goto done;
2628 }
2629 if (!data)
2630 {
2632 goto done;
2633 }
2634
2635 *size = stored_data->size;
2636 memcpy(data, stored_data->content.data, stored_data->size);
2637 hr = DD_OK;
2638
2639done:
2641 return hr;
2642}
2643
2644static HRESULT WINAPI ddraw_surface4_GetPrivateData(IDirectDrawSurface4 *iface, REFGUID tag, void *data, DWORD *size)
2645{
2646 struct ddraw_surface *surface = impl_from_IDirectDrawSurface4(iface);
2647
2648 TRACE("iface %p, tag %s, data %p, data_size %p.\n",
2649 iface, debugstr_guid(tag), data, size);
2650
2652}
2653
2654/*****************************************************************************
2655 * IDirectDrawSurface7::FreePrivateData
2656 *
2657 * Frees private data stored in the surface
2658 *
2659 * Params:
2660 * tag: Tag of the data to free
2661 *
2662 * Returns:
2663 * D3D_OK on success, error code otherwise.
2664 *
2665 *****************************************************************************/
2667{
2668 struct ddraw_surface *surface = impl_from_IDirectDrawSurface7(iface);
2670
2671 TRACE("iface %p, tag %s.\n", iface, debugstr_guid(tag));
2672
2675 if (!entry)
2676 {
2678 return DDERR_NOTFOUND;
2679 }
2680
2683
2684 return DD_OK;
2685}
2686
2687static HRESULT WINAPI ddraw_surface4_FreePrivateData(IDirectDrawSurface4 *iface, REFGUID tag)
2688{
2689 struct ddraw_surface *surface = impl_from_IDirectDrawSurface4(iface);
2690
2691 TRACE("iface %p, tag %s.\n", iface, debugstr_guid(tag));
2692
2694}
2695
2696/*****************************************************************************
2697 * IDirectDrawSurface7::PageLock
2698 *
2699 * Prevents a sysmem surface from being paged out
2700 *
2701 * Params:
2702 * Flags: Not used, must be 0(unchecked)
2703 *
2704 * Returns:
2705 * DD_OK, because it's a stub
2706 *
2707 *****************************************************************************/
2709{
2710 TRACE("iface %p, flags %#x.\n", iface, Flags);
2711
2712 /* This is Windows memory management related - we don't need this */
2713 return DD_OK;
2714}
2715
2716static HRESULT WINAPI ddraw_surface4_PageLock(IDirectDrawSurface4 *iface, DWORD flags)
2717{
2718 struct ddraw_surface *surface = impl_from_IDirectDrawSurface4(iface);
2719
2720 TRACE("iface %p, flags %#x.\n", iface, flags);
2721
2723}
2724
2725static HRESULT WINAPI ddraw_surface3_PageLock(IDirectDrawSurface3 *iface, DWORD flags)
2726{
2727 struct ddraw_surface *surface = impl_from_IDirectDrawSurface3(iface);
2728
2729 TRACE("iface %p, flags %#x.\n", iface, flags);
2730
2732}
2733
2734static HRESULT WINAPI ddraw_surface2_PageLock(IDirectDrawSurface2 *iface, DWORD flags)
2735{
2736 struct ddraw_surface *surface = impl_from_IDirectDrawSurface2(iface);
2737
2738 TRACE("iface %p, flags %#x.\n", iface, flags);
2739
2741}
2742
2743/*****************************************************************************
2744 * IDirectDrawSurface7::PageUnlock
2745 *
2746 * Allows a sysmem surface to be paged out
2747 *
2748 * Params:
2749 * Flags: Not used, must be 0(unchecked)
2750 *
2751 * Returns:
2752 * DD_OK, because it's a stub
2753 *
2754 *****************************************************************************/
2756{
2757 TRACE("iface %p, flags %#x.\n", iface, Flags);
2758
2759 return DD_OK;
2760}
2761
2762static HRESULT WINAPI ddraw_surface4_PageUnlock(IDirectDrawSurface4 *iface, DWORD flags)
2763{
2764 struct ddraw_surface *surface = impl_from_IDirectDrawSurface4(iface);
2765
2766 TRACE("iface %p, flags %#x.\n", iface, flags);
2767
2769}
2770
2771static HRESULT WINAPI ddraw_surface3_PageUnlock(IDirectDrawSurface3 *iface, DWORD flags)
2772{
2773 struct ddraw_surface *surface = impl_from_IDirectDrawSurface3(iface);
2774
2775 TRACE("iface %p, flags %#x.\n", iface, flags);
2776
2778}
2779
2780static HRESULT WINAPI ddraw_surface2_PageUnlock(IDirectDrawSurface2 *iface, DWORD flags)
2781{
2782 struct ddraw_surface *surface = impl_from_IDirectDrawSurface2(iface);
2783
2784 TRACE("iface %p, flags %#x.\n", iface, flags);
2785
2787}
2788
2789/*****************************************************************************
2790 * IDirectDrawSurface7::BltBatch
2791 *
2792 * An unimplemented function
2793 *
2794 * Params:
2795 * ?
2796 *
2797 * Returns:
2798 * DDERR_UNSUPPORTED
2799 *
2800 *****************************************************************************/
2802{
2803 TRACE("iface %p, batch %p, count %u, flags %#x.\n", iface, Batch, Count, Flags);
2804
2805 /* MSDN: "not currently implemented" */
2806 return DDERR_UNSUPPORTED;
2807}
2808
2810{
2811 struct ddraw_surface *surface = impl_from_IDirectDrawSurface4(iface);
2812
2813 TRACE("iface %p, batch %p, count %u, flags %#x.\n", iface, batch, count, flags);
2814
2816}
2817
2819{
2820 struct ddraw_surface *surface = impl_from_IDirectDrawSurface3(iface);
2821
2822 TRACE("iface %p, batch %p, count %u, flags %#x.\n", iface, batch, count, flags);
2823
2825}
2826
2828{
2829 struct ddraw_surface *surface = impl_from_IDirectDrawSurface2(iface);
2830
2831 TRACE("iface %p, batch %p, count %u, flags %#x.\n", iface, batch, count, flags);
2832
2834}
2835
2837{
2838 struct ddraw_surface *surface = impl_from_IDirectDrawSurface(iface);
2839
2840 TRACE("iface %p, batch %p, count %u, flags %#x.\n", iface, batch, count, flags);
2841
2843}
2844
2845/*****************************************************************************
2846 * IDirectDrawSurface7::EnumAttachedSurfaces
2847 *
2848 * Enumerates all surfaces attached to this surface
2849 *
2850 * Params:
2851 * context: Pointer to pass unmodified to the callback
2852 * cb: Callback function to call for each surface
2853 *
2854 * Returns:
2855 * DD_OK on success
2856 * DDERR_INVALIDPARAMS if cb is NULL
2857 *
2858 *****************************************************************************/
2861{
2862 struct ddraw_surface *surface = impl_from_IDirectDrawSurface7(iface);
2863 struct ddraw_surface *surf;
2865 int i;
2866
2867 /* Attached surfaces aren't handled in WineD3D */
2868 TRACE("iface %p, context %p, callback %p.\n", iface, context, cb);
2869
2870 if(!cb)
2871 return DDERR_INVALIDPARAMS;
2872
2874
2875 for(i = 0; i < MAX_COMPLEX_ATTACHED; i++)
2876 {
2877 surf = surface->complex_array[i];
2878 if(!surf) break;
2879
2881 desc = surf->surface_desc;
2882 /* check: != DDENUMRET_OK or == DDENUMRET_CANCEL? */
2884 {
2886 return DD_OK;
2887 }
2888 }
2889
2890 for (surf = surface->next_attached; surf != NULL; surf = surf->next_attached)
2891 {
2893 desc = surf->surface_desc;
2894 /* check: != DDENUMRET_OK or == DDENUMRET_CANCEL? */
2896 {
2898 return DD_OK;
2899 }
2900 }
2901
2902 TRACE(" end of enumeration.\n");
2903
2905
2906 return DD_OK;
2907}
2908
2910{
2912 void *context;
2913};
2914
2915struct callback_info
2916{
2918 void *context;
2919};
2920
2922{
2923 struct ddraw_surface *surface_impl = impl_from_IDirectDrawSurface7(surface);
2924 const struct callback_info2 *info = context;
2925
2927 ddraw_surface7_Release(surface);
2928
2929 return info->callback(&surface_impl->IDirectDrawSurface4_iface, surface_desc, info->context);
2930}
2931
2933{
2934 struct ddraw_surface *surface_impl = impl_from_IDirectDrawSurface7(surface);
2935 const struct callback_info *info = context;
2936
2938 ddraw_surface7_Release(surface);
2939
2940 /* FIXME: Check surface_test.dwSize */
2941 return info->callback(&surface_impl->IDirectDrawSurface_iface,
2942 (DDSURFACEDESC *)surface_desc, info->context);
2943}
2944
2945static HRESULT WINAPI ddraw_surface4_EnumAttachedSurfaces(IDirectDrawSurface4 *iface,
2947{
2948 struct ddraw_surface *surface = impl_from_IDirectDrawSurface4(iface);
2949 struct callback_info2 info;
2950
2951 TRACE("iface %p, context %p, callback %p.\n", iface, context, callback);
2952
2953 info.callback = callback;
2954 info.context = context;
2955
2958}
2959
2960static HRESULT WINAPI ddraw_surface3_EnumAttachedSurfaces(IDirectDrawSurface3 *iface,
2962{
2963 struct ddraw_surface *surface = impl_from_IDirectDrawSurface3(iface);
2964 struct callback_info info;
2965
2966 TRACE("iface %p, context %p, callback %p.\n", iface, context, callback);
2967
2968 info.callback = callback;
2969 info.context = context;
2970
2972 &info, EnumCallback);
2973}
2974
2975static HRESULT WINAPI ddraw_surface2_EnumAttachedSurfaces(IDirectDrawSurface2 *iface,
2977{
2978 struct ddraw_surface *surface = impl_from_IDirectDrawSurface2(iface);
2979 struct callback_info info;
2980
2981 TRACE("iface %p, context %p, callback %p.\n", iface, context, callback);
2982
2983 info.callback = callback;
2984 info.context = context;
2985
2987 &info, EnumCallback);
2988}
2989
2990static HRESULT WINAPI ddraw_surface1_EnumAttachedSurfaces(IDirectDrawSurface *iface,
2992{
2993 struct ddraw_surface *surface = impl_from_IDirectDrawSurface(iface);
2994 struct callback_info info;
2995
2996 TRACE("iface %p, context %p, callback %p.\n", iface, context, callback);
2997
2998 info.callback = callback;
2999 info.context = context;
3000
3002 &info, EnumCallback);
3003}
3004
3005/*****************************************************************************
3006 * IDirectDrawSurface7::EnumOverlayZOrders
3007 *
3008 * "Enumerates the overlay surfaces on the specified destination"
3009 *
3010 * Params:
3011 * Flags: DDENUMOVERLAYZ_BACKTOFRONT or DDENUMOVERLAYZ_FRONTTOBACK
3012 * context: context to pass back to the callback
3013 * cb: callback function to call for each enumerated surface
3014 *
3015 * Returns:
3016 * DD_OK, because it's a stub
3017 *
3018 *****************************************************************************/
3021{
3022 FIXME("iface %p, flags %#x, context %p, callback %p stub!\n", iface, Flags, context, cb);
3023
3024 return DD_OK;
3025}
3026
3027static HRESULT WINAPI ddraw_surface4_EnumOverlayZOrders(IDirectDrawSurface4 *iface,
3029{
3030 struct ddraw_surface *surface = impl_from_IDirectDrawSurface4(iface);
3031 struct callback_info2 info;
3032
3033 TRACE("iface %p, flags %#x, context %p, callback %p.\n", iface, flags, context, callback);
3034
3035 info.callback = callback;
3036 info.context = context;
3037
3040}
3041
3042static HRESULT WINAPI ddraw_surface3_EnumOverlayZOrders(IDirectDrawSurface3 *iface,
3044{
3045 struct ddraw_surface *surface = impl_from_IDirectDrawSurface3(iface);
3046 struct callback_info info;
3047
3048 TRACE("iface %p, flags %#x, context %p, callback %p.\n", iface, flags, context, callback);
3049
3050 info.callback = callback;
3051 info.context = context;
3052
3055}
3056
3057static HRESULT WINAPI ddraw_surface2_EnumOverlayZOrders(IDirectDrawSurface2 *iface,
3059{
3060 struct ddraw_surface *surface = impl_from_IDirectDrawSurface2(iface);
3061 struct callback_info info;
3062
3063 TRACE("iface %p, flags %#x, context %p, callback %p.\n", iface, flags, context, callback);
3064
3065 info.callback = callback;
3066 info.context = context;
3067
3070}
3071
3072static HRESULT WINAPI ddraw_surface1_EnumOverlayZOrders(IDirectDrawSurface *iface,
3074{
3075 struct ddraw_surface *surface = impl_from_IDirectDrawSurface(iface);
3076 struct callback_info info;
3077
3078 TRACE("iface %p, flags %#x, context %p, callback %p.\n", iface, flags, context, callback);
3079
3080 info.callback = callback;
3081 info.context = context;
3082
3085}
3086
3087/*****************************************************************************
3088 * IDirectDrawSurface7::GetBltStatus
3089 *
3090 * Returns the blitting status
3091 *
3092 * Params:
3093 * Flags: DDGBS_CANBLT or DDGBS_ISBLTDONE
3094 *
3095 *****************************************************************************/
3097{
3098 TRACE("iface %p, flags %#x.\n", iface, Flags);
3099
3100 switch (Flags)
3101 {
3102 case WINEDDGBS_CANBLT:
3104 return DD_OK;
3105
3106 default:
3107 return DDERR_INVALIDPARAMS;
3108 }
3109}
3110
3111static HRESULT WINAPI ddraw_surface4_GetBltStatus(IDirectDrawSurface4 *iface, DWORD flags)
3112{
3113 struct ddraw_surface *surface = impl_from_IDirectDrawSurface4(iface);
3114
3115 TRACE("iface %p, flags %#x.\n", iface, flags);
3116
3118}
3119
3120static HRESULT WINAPI ddraw_surface3_GetBltStatus(IDirectDrawSurface3 *iface, DWORD flags)
3121{
3122 struct ddraw_surface *surface = impl_from_IDirectDrawSurface3(iface);
3123
3124 TRACE("iface %p, flags %#x.\n", iface, flags);
3125
3127}
3128
3129static HRESULT WINAPI ddraw_surface2_GetBltStatus(IDirectDrawSurface2 *iface, DWORD flags)
3130{
3131 struct ddraw_surface *surface = impl_from_IDirectDrawSurface2(iface);
3132
3133 TRACE("iface %p, flags %#x.\n", iface, flags);
3134
3136}
3137
3138static HRESULT WINAPI ddraw_surface1_GetBltStatus(IDirectDrawSurface *iface, DWORD flags)
3139{
3140 struct ddraw_surface *surface = impl_from_IDirectDrawSurface(iface);
3141
3142 TRACE("iface %p, flags %#x.\n", iface, flags);
3143
3145}
3146
3147/*****************************************************************************
3148 * IDirectDrawSurface7::GetColorKey
3149 *
3150 * Returns the color key assigned to the surface
3151 *
3152 * Params:
3153 * Flags: Some flags
3154 * CKey: Address to store the key to
3155 *
3156 * Returns:
3157 * DD_OK on success
3158 * DDERR_INVALIDPARAMS if CKey is NULL
3159 *
3160 *****************************************************************************/
3162{
3164
3165 TRACE("iface %p, flags %#x, color_key %p.\n", iface, Flags, CKey);
3166
3167 if(!CKey)
3168 return DDERR_INVALIDPARAMS;
3169
3171
3172 switch (Flags)
3173 {
3174 case DDCKEY_DESTBLT:
3175 if (!(This->surface_desc.dwFlags & DDSD_CKDESTBLT))
3176 {
3178 return DDERR_NOCOLORKEY;
3179 }
3180 *CKey = This->surface_desc.ddckCKDestBlt;
3181 break;
3182
3183 case DDCKEY_DESTOVERLAY:
3184 if (!(This->surface_desc.dwFlags & DDSD_CKDESTOVERLAY))
3185 {
3187 return DDERR_NOCOLORKEY;
3188 }
3189 *CKey = This->surface_desc.u3.ddckCKDestOverlay;
3190 break;
3191
3192 case DDCKEY_SRCBLT:
3193 if (!(This->surface_desc.dwFlags & DDSD_CKSRCBLT))
3194 {
3196 return DDERR_NOCOLORKEY;
3197 }
3198 *CKey = This->surface_desc.ddckCKSrcBlt;
3199 break;
3200
3201 case DDCKEY_SRCOVERLAY:
3202 if (!(This->surface_desc.dwFlags & DDSD_CKSRCOVERLAY))
3203 {
3205 return DDERR_NOCOLORKEY;
3206 }
3207 *CKey = This->surface_desc.ddckCKSrcOverlay;
3208 break;
3209
3210 default:
3212 return DDERR_INVALIDPARAMS;
3213 }
3214
3216
3217 return DD_OK;
3218}
3219
3221{
3222 struct ddraw_surface *surface = impl_from_IDirectDrawSurface4(iface);
3223
3224 TRACE("iface %p, flags %#x, color_key %p.\n", iface, flags, color_key);
3225
3227}
3228
3230{
3231 struct ddraw_surface *surface = impl_from_IDirectDrawSurface3(iface);
3232
3233 TRACE("iface %p, flags %#x, color_key %p.\n", iface, flags, color_key);
3234
3236}
3237
3239{
3240 struct ddraw_surface *surface = impl_from_IDirectDrawSurface2(iface);
3241
3242 TRACE("iface %p, flags %#x, color_key %p.\n", iface, flags, color_key);
3243
3245}
3246
3248{
3249 struct ddraw_surface *surface = impl_from_IDirectDrawSurface(iface);
3250
3251 TRACE("iface %p, flags %#x, color_key %p.\n", iface, flags, color_key);
3252
3254}
3255
3256/*****************************************************************************
3257 * IDirectDrawSurface7::GetFlipStatus
3258 *
3259 * Returns the flipping status of the surface
3260 *
3261 * Params:
3262 * Flags: DDGFS_CANFLIP of DDGFS_ISFLIPDONE
3263 *
3264 *****************************************************************************/
3266{
3267 TRACE("iface %p, flags %#x.\n", iface, Flags);
3268
3269 /* XXX: DDERR_INVALIDSURFACETYPE */
3270
3271 switch (Flags)
3272 {
3273 case WINEDDGFS_CANFLIP:
3275 return DD_OK;
3276
3277 default:
3278 return DDERR_INVALIDPARAMS;
3279 }
3280}
3281
3282static HRESULT WINAPI ddraw_surface4_GetFlipStatus(IDirectDrawSurface4 *iface, DWORD flags)
3283{
3284 struct ddraw_surface *surface = impl_from_IDirectDrawSurface4(iface);
3285
3286 TRACE("iface %p, flags %#x.\n", iface, flags);
3287
3289}
3290
3291static HRESULT WINAPI ddraw_surface3_GetFlipStatus(IDirectDrawSurface3 *iface, DWORD flags)
3292{
3293 struct ddraw_surface *surface = impl_from_IDirectDrawSurface3(iface);
3294
3295 TRACE("iface %p, flags %#x.\n", iface, flags);
3296
3298}
3299
3300static HRESULT WINAPI ddraw_surface2_GetFlipStatus(IDirectDrawSurface2 *iface, DWORD flags)
3301{
3302 struct ddraw_surface *surface = impl_from_IDirectDrawSurface2(iface);
3303
3304 TRACE("iface %p, flags %#x.\n", iface, flags);
3305
3307}
3308
3309static HRESULT WINAPI ddraw_surface1_GetFlipStatus(IDirectDrawSurface *iface, DWORD flags)
3310{
3311 struct ddraw_surface *surface = impl_from_IDirectDrawSurface(iface);
3312
3313 TRACE("iface %p, flags %#x.\n", iface, flags);
3314
3316}
3317
3318/*****************************************************************************
3319 * IDirectDrawSurface7::GetOverlayPosition
3320 *
3321 * Returns the display coordinates of a visible and active overlay surface
3322 *
3323 * Params:
3324 * X
3325 * Y
3326 *
3327 * Returns:
3328 * DDERR_NOTAOVERLAYSURFACE, because it's a stub
3329 *****************************************************************************/
3331{
3332 struct ddraw_surface *surface = impl_from_IDirectDrawSurface7(iface);
3333 HRESULT hr;
3334
3335 TRACE("iface %p, x %p, y %p.\n", iface, x, y);
3336
3339 surface->sub_resource_idx, x, y);
3341
3342 return hr;
3343}
3344
3345static HRESULT WINAPI ddraw_surface4_GetOverlayPosition(IDirectDrawSurface4 *iface, LONG *x, LONG *y)
3346{
3347 struct ddraw_surface *surface = impl_from_IDirectDrawSurface4(iface);
3348
3349 TRACE("iface %p, x %p, y %p.\n", iface, x, y);
3350
3352}
3353
3354static HRESULT WINAPI ddraw_surface3_GetOverlayPosition(IDirectDrawSurface3 *iface, LONG *x, LONG *y)
3355{
3356 struct ddraw_surface *surface = impl_from_IDirectDrawSurface3(iface);
3357
3358 TRACE("iface %p, x %p, y %p.\n", iface, x, y);
3359
3361}
3362
3363static HRESULT WINAPI ddraw_surface2_GetOverlayPosition(IDirectDrawSurface2 *iface, LONG *x, LONG *y)
3364{
3365 struct ddraw_surface *surface = impl_from_IDirectDrawSurface2(iface);
3366
3367 TRACE("iface %p, x %p, y %p.\n", iface, x, y);
3368
3370}
3371
3372static HRESULT WINAPI ddraw_surface1_GetOverlayPosition(IDirectDrawSurface *iface, LONG *x, LONG *y)
3373{
3374 struct ddraw_surface *surface = impl_from_IDirectDrawSurface(iface);
3375
3376 TRACE("iface %p, x %p, y %p.\n", iface, x, y);
3377
3379}
3380
3381/*****************************************************************************
3382 * IDirectDrawSurface7::GetPixelFormat
3383 *
3384 * Returns the pixel format of the Surface
3385 *
3386 * Params:
3387 * PixelFormat: Pointer to a DDPIXELFORMAT structure to which the pixel
3388 * format should be written
3389 *
3390 * Returns:
3391 * DD_OK on success
3392 * DDERR_INVALIDPARAMS if PixelFormat is NULL
3393 *
3394 *****************************************************************************/
3396{
3397 /* What is DDERR_INVALIDSURFACETYPE for here? */
3398 struct ddraw_surface *surface = impl_from_IDirectDrawSurface7(iface);
3399
3400 TRACE("iface %p, pixel_format %p.\n", iface, PixelFormat);
3401
3402 if(!PixelFormat)
3403 return DDERR_INVALIDPARAMS;
3404
3408
3409 return DD_OK;
3410}
3411
3413{
3414 struct ddraw_surface *surface = impl_from_IDirectDrawSurface4(iface);
3415
3416 TRACE("iface %p, pixel_format %p.\n", iface, pixel_format);
3417
3419}
3420
3422{
3423 struct ddraw_surface *surface = impl_from_IDirectDrawSurface3(iface);
3424
3425 TRACE("iface %p, pixel_format %p.\n", iface, pixel_format);
3426
3428}
3429
3431{
3432 struct ddraw_surface *surface = impl_from_IDirectDrawSurface2(iface);
3433
3434 TRACE("iface %p, pixel_format %p.\n", iface, pixel_format);
3435
3437}
3438
3440{
3441 struct ddraw_surface *surface = impl_from_IDirectDrawSurface(iface);
3442
3443 TRACE("iface %p, pixel_format %p.\n", iface, pixel_format);
3444
3446}
3447
3448/*****************************************************************************
3449 * IDirectDrawSurface7::GetSurfaceDesc
3450 *
3451 * Returns the description of this surface
3452 *
3453 * Params:
3454 * DDSD: Address of a DDSURFACEDESC2 structure that is to be filled with the
3455 * surface desc
3456 *
3457 * Returns:
3458 * DD_OK on success
3459 * DDERR_INVALIDPARAMS if DDSD is NULL
3460 *
3461 *****************************************************************************/
3463{
3464 struct ddraw_surface *surface = impl_from_IDirectDrawSurface7(iface);
3465
3466 TRACE("iface %p, surface_desc %p.\n", iface, DDSD);
3467
3468 if(!DDSD)
3469 return DDERR_INVALIDPARAMS;
3470
3471 if (DDSD->dwSize != sizeof(DDSURFACEDESC2))
3472 {
3473 WARN("Incorrect struct size %d, returning DDERR_INVALIDPARAMS\n",DDSD->dwSize);
3474 return DDERR_INVALIDPARAMS;
3475 }
3476
3478 DD_STRUCT_COPY_BYSIZE(DDSD, &surface->surface_desc);
3479 TRACE("Returning surface desc:\n");
3482
3483 return DD_OK;
3484}
3485
3486static HRESULT WINAPI ddraw_surface4_GetSurfaceDesc(IDirectDrawSurface4 *iface, DDSURFACEDESC2 *DDSD)
3487{
3488 struct ddraw_surface *surface = impl_from_IDirectDrawSurface4(iface);
3489
3490 TRACE("iface %p, surface_desc %p.\n", iface, DDSD);
3491
3493}
3494
3496{
3497 struct ddraw_surface *surface = impl_from_IDirectDrawSurface3(iface);
3498
3499 TRACE("iface %p, surface_desc %p.\n", iface, surface_desc);
3500
3501 if (!surface_desc) return DDERR_INVALIDPARAMS;
3502
3503 if (surface_desc->dwSize != sizeof(DDSURFACEDESC))
3504 {
3505 WARN("Incorrect structure size %u, returning DDERR_INVALIDPARAMS.\n", surface_desc->dwSize);
3506 return DDERR_INVALIDPARAMS;
3507 }
3508
3511 TRACE("Returning surface desc:\n");
3512 if (TRACE_ON(ddraw))
3513 {
3514 /* DDRAW_dump_surface_desc handles the smaller size */
3516 }
3518
3519 return DD_OK;
3520}
3521
3522static HRESULT WINAPI ddraw_surface2_GetSurfaceDesc(IDirectDrawSurface2 *iface, DDSURFACEDESC *DDSD)
3523{
3524 struct ddraw_surface *surface = impl_from_IDirectDrawSurface2(iface);
3525
3526 TRACE("iface %p, surface_desc %p.\n", iface, DDSD);
3527
3529}
3530
3531static HRESULT WINAPI ddraw_surface1_GetSurfaceDesc(IDirectDrawSurface *iface, DDSURFACEDESC *DDSD)
3532{
3533 struct ddraw_surface *surface = impl_from_IDirectDrawSurface(iface);
3534
3535 TRACE("iface %p, surface_desc %p.\n", iface, DDSD);
3536
3538}
3539
3540/*****************************************************************************
3541 * IDirectDrawSurface7::Initialize
3542 *
3543 * Initializes the surface. This is a no-op in Wine
3544 *
3545 * Params:
3546 * DD: Pointer to an DirectDraw interface
3547 * DDSD: Surface description for initialization
3548 *
3549 * Returns:
3550 * DDERR_ALREADYINITIALIZED
3551 *
3552 *****************************************************************************/
3554 IDirectDraw *ddraw, DDSURFACEDESC2 *surface_desc)
3555{
3556 TRACE("iface %p, ddraw %p, surface_desc %p.\n", iface, ddraw, surface_desc);
3557
3559}
3560
3561static HRESULT WINAPI ddraw_surface4_Initialize(IDirectDrawSurface4 *iface,
3562 IDirectDraw *ddraw, DDSURFACEDESC2 *surface_desc)
3563{
3564 struct ddraw_surface *surface = impl_from_IDirectDrawSurface4(iface);
3565
3566 TRACE("iface %p, ddraw %p, surface_desc %p.\n", iface, ddraw, surface_desc);
3567
3570}
3571
3572static HRESULT WINAPI ddraw_surface3_Initialize(IDirectDrawSurface3 *iface,
3573 IDirectDraw *ddraw, DDSURFACEDESC *surface_desc)
3574{
3575 struct ddraw_surface *surface = impl_from_IDirectDrawSurface3(iface);
3576 DDSURFACEDESC2 surface_desc2;
3577
3578 TRACE("iface %p, ddraw %p, surface_desc %p.\n", iface, ddraw, surface_desc);
3579
3580 if (surface_desc) DDSD_to_DDSD2(surface_desc, &surface_desc2);
3582 ddraw, surface_desc ? &surface_desc2 : NULL);
3583}
3584
3585static HRESULT WINAPI ddraw_surface2_Initialize(IDirectDrawSurface2 *iface,
3586 IDirectDraw *ddraw, DDSURFACEDESC *surface_desc)
3587{
3588 struct ddraw_surface *surface = impl_from_IDirectDrawSurface2(iface);
3589 DDSURFACEDESC2 surface_desc2;
3590
3591 TRACE("iface %p, ddraw %p, surface_desc %p.\n", iface, ddraw, surface_desc);
3592
3593 if (surface_desc) DDSD_to_DDSD2(surface_desc, &surface_desc2);
3595 ddraw, surface_desc ? &surface_desc2 : NULL);
3596}
3597
3598static HRESULT WINAPI ddraw_surface1_Initialize(IDirectDrawSurface *iface,
3599 IDirectDraw *ddraw, DDSURFACEDESC *surface_desc)
3600{
3601 struct ddraw_surface *surface = impl_from_IDirectDrawSurface(iface);
3602 DDSURFACEDESC2 surface_desc2;
3603
3604 TRACE("iface %p, ddraw %p, surface_desc %p.\n", iface, ddraw, surface_desc);
3605
3606 if (surface_desc) DDSD_to_DDSD2(surface_desc, &surface_desc2);
3608 ddraw, surface_desc ? &surface_desc2 : NULL);
3609}
3610
3611/*****************************************************************************
3612 * IDirect3DTexture1::Initialize
3613 *
3614 * The sdk says it's not implemented
3615 *
3616 * Params:
3617 * ?
3618 *
3619 * Returns
3620 * DDERR_UNSUPPORTED
3621 *
3622 *****************************************************************************/
3623static HRESULT WINAPI d3d_texture1_Initialize(IDirect3DTexture *iface,
3624 IDirect3DDevice *device, IDirectDrawSurface *surface)
3625{
3626 TRACE("iface %p, device %p, surface %p.\n", iface, device, surface);
3627
3628 return DDERR_UNSUPPORTED; /* Unchecked */
3629}
3630
3631/*****************************************************************************
3632 * IDirectDrawSurface7::IsLost
3633 *
3634 * Checks if the surface is lost
3635 *
3636 * Returns:
3637 * DD_OK, if the surface is usable
3638 * DDERR_ISLOST if the surface is lost
3639 *
3640 *****************************************************************************/
3642{
3643 struct ddraw_surface *surface = impl_from_IDirectDrawSurface7(iface);
3644
3645 TRACE("iface %p.\n", iface);
3646
3647 if (surface->ddraw->device_state != DDRAW_DEVICE_STATE_OK || surface->is_lost)
3648 return DDERR_SURFACELOST;
3649
3650 return DD_OK;
3651}
3652
3653static HRESULT WINAPI ddraw_surface4_IsLost(IDirectDrawSurface4 *iface)
3654{
3655 struct ddraw_surface *surface = impl_from_IDirectDrawSurface4(iface);
3656
3657 TRACE("iface %p.\n", iface);
3658
3660}
3661
3662static HRESULT WINAPI ddraw_surface3_IsLost(IDirectDrawSurface3 *iface)
3663{
3664 struct ddraw_surface *surface = impl_from_IDirectDrawSurface3(iface);
3665
3666 TRACE("iface %p.\n", iface);
3667
3669}
3670
3671static HRESULT WINAPI ddraw_surface2_IsLost(IDirectDrawSurface2 *iface)
3672{
3673 struct ddraw_surface *surface = impl_from_IDirectDrawSurface2(iface);
3674
3675 TRACE("iface %p.\n", iface);
3676
3678}
3679
3680static HRESULT WINAPI ddraw_surface1_IsLost(IDirectDrawSurface *iface)
3681{
3682 struct ddraw_surface *surface = impl_from_IDirectDrawSurface(iface);
3683
3684 TRACE("iface %p.\n", iface);
3685
3687}
3688
3689/*****************************************************************************
3690 * IDirectDrawSurface7::Restore
3691 *
3692 * Restores a lost surface. This makes the surface usable again, but
3693 * doesn't reload its old contents
3694 *
3695 * Returns:
3696 * DD_OK on success, error code otherwise.
3697 *
3698 *****************************************************************************/
3700{
3701 struct ddraw_surface *surface = impl_from_IDirectDrawSurface7(iface);
3702
3703 TRACE("iface %p.\n", iface);
3704
3706 {
3707 struct wined3d_swapchain *swapchain = surface->ddraw->wined3d_swapchain;
3708 struct wined3d_sub_resource_desc wined3d_desc;
3710 HRESULT hr;
3711
3713 {
3714 WARN("Failed to get display mode, hr %#x.\n", hr);
3715 return hr;
3716 }
3717
3718 if (FAILED(hr = wined3d_texture_get_sub_resource_desc(surface->wined3d_texture, 0, &wined3d_desc)))
3719 {
3720 WARN("Failed to get resource desc, hr %#x.\n", hr);
3721 return hr;
3722 }
3723
3724 if (mode.width != wined3d_desc.width || mode.height != wined3d_desc.height)
3725 {
3726 WARN("Display mode dimensions %ux%u don't match surface dimensions %ux%u.\n",
3727 mode.width, mode.height, wined3d_desc.width, wined3d_desc.height);
3728 return DDERR_WRONGMODE;
3729 }
3730
3731 if (mode.format_id != wined3d_desc.format)
3732 {
3733 WARN("Display mode format %#x doesn't match surface format %#x.\n",
3734 mode.format_id, wined3d_desc.format);
3735 return DDERR_WRONGMODE;
3736 }
3737 }
3738
3740 surface->is_lost = FALSE;
3741
3742 return DD_OK;
3743}
3744
3745static HRESULT WINAPI ddraw_surface4_Restore(IDirectDrawSurface4 *iface)
3746{
3747 struct ddraw_surface *surface = impl_from_IDirectDrawSurface4(iface);
3748
3749 TRACE("iface %p.\n", iface);
3750
3752}
3753
3754static HRESULT WINAPI ddraw_surface3_Restore(IDirectDrawSurface3 *iface)
3755{
3756 struct ddraw_surface *surface = impl_from_IDirectDrawSurface3(iface);
3757
3758 TRACE("iface %p.\n", iface);
3759
3761}
3762
3763static HRESULT WINAPI ddraw_surface2_Restore(IDirectDrawSurface2 *iface)
3764{
3765 struct ddraw_surface *surface = impl_from_IDirectDrawSurface2(iface);
3766
3767 TRACE("iface %p.\n", iface);
3768
3770}
3771
3772static HRESULT WINAPI ddraw_surface1_Restore(IDirectDrawSurface *iface)
3773{
3774 struct ddraw_surface *surface = impl_from_IDirectDrawSurface(iface);
3775
3776 TRACE("iface %p.\n", iface);
3777
3779}
3780
3781/*****************************************************************************
3782 * IDirectDrawSurface7::SetOverlayPosition
3783 *
3784 * Changes the display coordinates of an overlay surface
3785 *
3786 * Params:
3787 * X:
3788 * Y:
3789 *
3790 * Returns:
3791 * DDERR_NOTAOVERLAYSURFACE, because we don't support overlays right now
3792 *****************************************************************************/
3794{
3795 struct ddraw_surface *surface = impl_from_IDirectDrawSurface7(iface);
3796 HRESULT hr;
3797
3798 TRACE("iface %p, x %d, y %d.\n", iface, x, y);
3799
3802 surface->sub_resource_idx, x, y);
3804
3805 return hr;
3806}
3807
3808static HRESULT WINAPI ddraw_surface4_SetOverlayPosition(IDirectDrawSurface4 *iface, LONG x, LONG y)
3809{
3810 struct ddraw_surface *surface = impl_from_IDirectDrawSurface4(iface);
3811
3812 TRACE("iface %p, x %d, y %d.\n", iface, x, y);
3813
3815}
3816
3817static HRESULT WINAPI ddraw_surface3_SetOverlayPosition(IDirectDrawSurface3 *iface, LONG x, LONG y)
3818{
3819 struct ddraw_surface *surface = impl_from_IDirectDrawSurface3(iface);
3820
3821 TRACE("iface %p, x %d, y %d.\n", iface, x, y);
3822
3824}
3825
3826static HRESULT WINAPI ddraw_surface2_SetOverlayPosition(IDirectDrawSurface2 *iface, LONG x, LONG y)
3827{
3828 struct ddraw_surface *surface = impl_from_IDirectDrawSurface2(iface);
3829
3830 TRACE("iface %p, x %d, y %d.\n", iface, x, y);
3831
3833}
3834
3835static HRESULT WINAPI ddraw_surface1_SetOverlayPosition(IDirectDrawSurface *iface, LONG x, LONG y)
3836{
3837 struct ddraw_surface *surface = impl_from_IDirectDrawSurface(iface);
3838
3839 TRACE("iface %p, x %d, y %d.\n", iface, x, y);
3840
3842}
3843
3844/*****************************************************************************
3845 * IDirectDrawSurface7::UpdateOverlay
3846 *
3847 * Modifies the attributes of an overlay surface.
3848 *
3849 * Params:
3850 * SrcRect: The section of the source being used for the overlay
3851 * DstSurface: Address of the surface that is overlaid
3852 * DstRect: Place of the overlay
3853 * Flags: some DDOVER_* flags
3854 *
3855 * Returns:
3856 * DDERR_UNSUPPORTED, because we don't support overlays
3857 *
3858 *****************************************************************************/
3860 IDirectDrawSurface7 *dst_surface, RECT *dst_rect, DWORD flags, DDOVERLAYFX *fx)
3861{
3862 struct ddraw_surface *src_impl = impl_from_IDirectDrawSurface7(iface);
3863 struct ddraw_surface *dst_impl = unsafe_impl_from_IDirectDrawSurface7(dst_surface);
3864 struct wined3d_texture *dst_wined3d_texture = NULL;
3865 unsigned int dst_sub_resource_idx = 0;
3866 HRESULT hr;
3867
3868 TRACE("iface %p, src_rect %s, dst_surface %p, dst_rect %s, flags %#x, fx %p.\n",
3869 iface, wine_dbgstr_rect(src_rect), dst_surface, wine_dbgstr_rect(dst_rect), flags, fx);
3870
3871 if (fx)
3872 FIXME("Ignoring fx %p.\n", fx);
3873
3875 if (dst_impl)
3876 {
3877 dst_wined3d_texture = dst_impl->wined3d_texture;
3878 dst_sub_resource_idx = dst_impl->sub_resource_idx;
3879 }
3881 src_rect, dst_wined3d_texture, dst_sub_resource_idx, dst_rect, flags);
3883
3884 switch (hr)
3885 {
3889 default:
3890 return hr;
3891 }
3892}
3893
3894static HRESULT WINAPI ddraw_surface4_UpdateOverlay(IDirectDrawSurface4 *iface, RECT *src_rect,
3895 IDirectDrawSurface4 *dst_surface, RECT *dst_rect, DWORD flags, DDOVERLAYFX *fx)
3896{
3897 struct ddraw_surface *src_impl = impl_from_IDirectDrawSurface4(iface);
3898 struct ddraw_surface *dst_impl = unsafe_impl_from_IDirectDrawSurface4(dst_surface);
3899
3900 TRACE("iface %p, src_rect %s, dst_surface %p, dst_rect %s, flags %#x, fx %p.\n",
3901 iface, wine_dbgstr_rect(src_rect), dst_surface, wine_dbgstr_rect(dst_rect), flags, fx);
3902
3903 return ddraw_surface7_UpdateOverlay(&src_impl->IDirectDrawSurface7_iface, src_rect,
3904 dst_impl ? &dst_impl->IDirectDrawSurface7_iface : NULL, dst_rect, flags, fx);
3905}
3906
3907static HRESULT WINAPI ddraw_surface3_UpdateOverlay(IDirectDrawSurface3 *iface, RECT *src_rect,
3908 IDirectDrawSurface3 *dst_surface, RECT *dst_rect, DWORD flags, DDOVERLAYFX *fx)
3909{
3910 struct ddraw_surface *src_impl = impl_from_IDirectDrawSurface3(iface);
3911 struct ddraw_surface *dst_impl = unsafe_impl_from_IDirectDrawSurface3(dst_surface);
3912
3913 TRACE("iface %p, src_rect %s, dst_surface %p, dst_rect %s, flags %#x, fx %p.\n",
3914 iface, wine_dbgstr_rect(src_rect), dst_surface, wine_dbgstr_rect(dst_rect), flags, fx);
3915
3916 return ddraw_surface7_UpdateOverlay(&src_impl->IDirectDrawSurface7_iface, src_rect,
3917 dst_impl ? &dst_impl->IDirectDrawSurface7_iface : NULL, dst_rect, flags, fx);
3918}
3919
3920static HRESULT WINAPI ddraw_surface2_UpdateOverlay(IDirectDrawSurface2 *iface, RECT *src_rect,
3921 IDirectDrawSurface2 *dst_surface, RECT *dst_rect, DWORD flags, DDOVERLAYFX *fx)
3922{
3923 struct ddraw_surface *src_impl = impl_from_IDirectDrawSurface2(iface);
3924 struct ddraw_surface *dst_impl = unsafe_impl_from_IDirectDrawSurface2(dst_surface);
3925
3926 TRACE("iface %p, src_rect %s, dst_surface %p, dst_rect %s, flags %#x, fx %p.\n",
3927 iface, wine_dbgstr_rect(src_rect), dst_surface, wine_dbgstr_rect(dst_rect), flags, fx);
3928
3929 return ddraw_surface7_UpdateOverlay(&src_impl->IDirectDrawSurface7_iface, src_rect,
3930 dst_impl ? &dst_impl->IDirectDrawSurface7_iface : NULL, dst_rect, flags, fx);
3931}
3932
3933static HRESULT WINAPI ddraw_surface1_UpdateOverlay(IDirectDrawSurface *iface, RECT *src_rect,
3934 IDirectDrawSurface *dst_surface, RECT *dst_rect, DWORD flags, DDOVERLAYFX *fx)
3935{
3936 struct ddraw_surface *src_impl = impl_from_IDirectDrawSurface(iface);
3937 struct ddraw_surface *dst_impl = unsafe_impl_from_IDirectDrawSurface(dst_surface);
3938
3939 TRACE("iface %p, src_rect %s, dst_surface %p, dst_rect %s, flags %#x, fx %p.\n",
3940 iface, wine_dbgstr_rect(src_rect), dst_surface, wine_dbgstr_rect(dst_rect), flags, fx);
3941
3942 return ddraw_surface7_UpdateOverlay(&src_impl->IDirectDrawSurface7_iface, src_rect,
3943 dst_impl ? &dst_impl->IDirectDrawSurface7_iface : NULL, dst_rect, flags, fx);
3944}
3945
3946/*****************************************************************************
3947 * IDirectDrawSurface7::UpdateOverlayDisplay
3948 *
3949 * The DX7 sdk says that it's not implemented
3950 *
3951 * Params:
3952 * Flags: ?
3953 *
3954 * Returns: DDERR_UNSUPPORTED, because we don't support overlays
3955 *
3956 *****************************************************************************/
3958{
3959 TRACE("iface %p, flags %#x.\n", iface, Flags);
3960
3961 return DDERR_UNSUPPORTED;
3962}
3963
3965{
3966 struct ddraw_surface *surface = impl_from_IDirectDrawSurface4(iface);
3967
3968 TRACE("iface %p, flags %#x.\n", iface, flags);
3969
3971}
3972
3974{
3975 struct ddraw_surface *surface = impl_from_IDirectDrawSurface3(iface);
3976
3977 TRACE("iface %p, flags %#x.\n", iface, flags);