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