ReactOS  0.4.13-dev-464-g6b95727
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 
31 static struct ddraw_surface *unsafe_impl_from_IDirectDrawSurface2(IDirectDrawSurface2 *iface);
32 static struct ddraw_surface *unsafe_impl_from_IDirectDrawSurface3(IDirectDrawSurface3 *iface);
33 
34 static 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  const RECT *rect, BOOL read, unsigned int swap_interval)
45 {
46  struct wined3d_texture *dst_texture;
47  HDC surface_dc, screen_dc;
48  int x, y, w, h;
49  HRESULT hr;
50  BOOL ret;
51  RECT r;
52 
53  if (surface->ddraw->flags & DDRAW_SWAPPED && !read)
54  {
55  surface->ddraw->flags &= ~DDRAW_SWAPPED;
56  rect = NULL;
57  }
58 
59  if (!rect)
60  {
61  SetRect(&r, 0, 0, surface->surface_desc.dwWidth, surface->surface_desc.dwHeight);
62  rect = &r;
63  }
64 
65  x = rect->left;
66  y = rect->top;
67  w = rect->right - rect->left;
68  h = rect->bottom - rect->top;
69 
70  if (w <= 0 || h <= 0)
71  return DD_OK;
72 
73  if (surface->ddraw->swapchain_window && !(surface->ddraw->flags & DDRAW_GDI_FLIP))
74  {
75  /* Nothing to do, we control the frontbuffer, or at least the parts we
76  * care about. */
77  if (read)
78  return DD_OK;
79 
80  if (swap_interval)
81  dst_texture = wined3d_swapchain_get_back_buffer(surface->ddraw->wined3d_swapchain, 0);
82  else
83  dst_texture = surface->ddraw->wined3d_frontbuffer;
84 
85  if (SUCCEEDED(hr = wined3d_texture_blt(dst_texture, 0, rect, surface->wined3d_texture,
86  surface->sub_resource_idx, rect, 0, NULL, WINED3D_TEXF_POINT)) && swap_interval)
87  {
88  hr = wined3d_swapchain_present(surface->ddraw->wined3d_swapchain, rect, rect, NULL, swap_interval, 0);
89  surface->ddraw->flags |= DDRAW_SWAPPED;
90  }
91  return hr;
92  }
93 
94  if (FAILED(hr = wined3d_texture_get_dc(surface->wined3d_texture, surface->sub_resource_idx, &surface_dc)))
95  {
96  ERR("Failed to get surface DC, hr %#x.\n", hr);
97  return hr;
98  }
99  if (surface->palette)
100  wined3d_palette_apply_to_dc(surface->palette->wined3d_palette, surface_dc);
101 
102  if (!(screen_dc = GetDC(NULL)))
103  {
104  wined3d_texture_release_dc(surface->wined3d_texture, surface->sub_resource_idx, surface_dc);
105  ERR("Failed to get screen DC.\n");
106  return E_FAIL;
107  }
108 
109  if (read)
110  ret = BitBlt(surface_dc, x, y, w, h,
111  screen_dc, x, y, SRCCOPY);
112  else
113  ret = BitBlt(screen_dc, x, y, w, h,
114  surface_dc, x, y, SRCCOPY);
115 
116  ReleaseDC(NULL, screen_dc);
117  wined3d_texture_release_dc(surface->wined3d_texture, surface->sub_resource_idx, surface_dc);
118 
119  if (!ret)
120  {
121  ERR("Failed to blit to/from screen.\n");
122  return E_FAIL;
123  }
124 
125  return DD_OK;
126 }
127 
128 /*****************************************************************************
129  * IUnknown parts follow
130  *****************************************************************************/
131 
132 /*****************************************************************************
133  * IDirectDrawSurface7::QueryInterface
134  *
135  * A normal QueryInterface implementation. For QueryInterface rules
136  * see ddraw.c, IDirectDraw7::QueryInterface. This method
137  * can Query IDirectDrawSurface interfaces in all version, IDirect3DTexture
138  * in all versions, the IDirectDrawGammaControl interface and it can
139  * create an IDirect3DDevice. (Uses IDirect3D7::CreateDevice)
140  *
141  * Params:
142  * riid: The interface id queried for
143  * obj: Address to write the pointer to
144  *
145  * Returns:
146  * S_OK on success
147  * E_NOINTERFACE if the requested interface wasn't found
148  *
149  *****************************************************************************/
151 {
153 
154  TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), obj);
155 
156  /* According to COM docs, if the QueryInterface fails, obj should be set to NULL */
157  *obj = NULL;
158 
159  if(!riid)
160  return DDERR_INVALIDPARAMS;
161 
162  if (IsEqualGUID(riid, &IID_IDirectDrawSurface7))
163  {
164  IDirectDrawSurface7_AddRef(iface);
165  *obj = iface;
166  TRACE("(%p) returning IDirectDrawSurface7 interface at %p\n", This, *obj);
167  return S_OK;
168  }
169 
170  if (IsEqualGUID(riid, &IID_IDirectDrawSurface4))
171  {
172  IDirectDrawSurface4_AddRef(&This->IDirectDrawSurface4_iface);
173  *obj = &This->IDirectDrawSurface4_iface;
174  TRACE("(%p) returning IDirectDrawSurface4 interface at %p\n", This, *obj);
175  return S_OK;
176  }
177 
178  if (IsEqualGUID(riid, &IID_IDirectDrawSurface3))
179  {
180  IDirectDrawSurface3_AddRef(&This->IDirectDrawSurface3_iface);
181  *obj = &This->IDirectDrawSurface3_iface;
182  TRACE("(%p) returning IDirectDrawSurface3 interface at %p\n", This, *obj);
183  return S_OK;
184  }
185 
186  if (IsEqualGUID(riid, &IID_IDirectDrawSurface2))
187  {
188  IDirectDrawSurface2_AddRef(&This->IDirectDrawSurface2_iface);
189  *obj = &This->IDirectDrawSurface2_iface;
190  TRACE("(%p) returning IDirectDrawSurface2 interface at %p\n", This, *obj);
191  return S_OK;
192  }
193 
194  if (IsEqualGUID(riid, &IID_IDirectDrawSurface)
196  {
197  IDirectDrawSurface_AddRef(&This->IDirectDrawSurface_iface);
198  *obj = &This->IDirectDrawSurface_iface;
199  TRACE("(%p) returning IDirectDrawSurface interface at %p\n", This, *obj);
200  return S_OK;
201  }
202 
203  if (IsEqualGUID(riid, &IID_IDirectDrawGammaControl))
204  {
205  IDirectDrawGammaControl_AddRef(&This->IDirectDrawGammaControl_iface);
206  *obj = &This->IDirectDrawGammaControl_iface;
207  TRACE("(%p) returning IDirectDrawGammaControl interface at %p\n", This, *obj);
208  return S_OK;
209  }
210 
211  if (IsEqualGUID(riid, &IID_IDirectDrawColorControl))
212  {
213  WARN("Color control not implemented.\n");
214  *obj = NULL;
215  return E_NOINTERFACE;
216  }
217 
218  if (This->version != 7)
219  {
221  || IsEqualGUID(riid, &IID_IDirect3DHALDevice)
222  || IsEqualGUID(riid, &IID_IDirect3DRGBDevice))
223  {
225  if (!This->device1)
226  {
227  HRESULT hr;
228 
229  if (FAILED(hr = d3d_device_create(This->ddraw, riid, This, (IUnknown *)&This->IDirectDrawSurface_iface,
230  1, &This->device1, (IUnknown *)&This->IDirectDrawSurface_iface)))
231  {
232  This->device1 = NULL;
234  WARN("Failed to create device, hr %#x.\n", hr);
235  return hr;
236  }
237  }
239 
240  IDirect3DDevice_AddRef(&This->device1->IDirect3DDevice_iface);
241  *obj = &This->device1->IDirect3DDevice_iface;
242  return S_OK;
243  }
244 
245  if (IsEqualGUID(&IID_IDirect3DTexture2, riid))
246  {
247  IDirect3DTexture2_AddRef(&This->IDirect3DTexture2_iface);
248  *obj = &This->IDirect3DTexture2_iface;
249  return S_OK;
250  }
251 
252  if (IsEqualGUID( &IID_IDirect3DTexture, riid ))
253  {
254  IDirect3DTexture2_AddRef(&This->IDirect3DTexture_iface);
255  *obj = &This->IDirect3DTexture_iface;
256  return S_OK;
257  }
258  }
259 
260  WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
261 
262  if (This->version != 7)
263  return E_INVALIDARG;
264 
265  return E_NOINTERFACE;
266 }
267 
268 static HRESULT WINAPI ddraw_surface4_QueryInterface(IDirectDrawSurface4 *iface, REFIID riid, void **object)
269 {
270  struct ddraw_surface *surface = impl_from_IDirectDrawSurface4(iface);
271 
272  TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
273 
275 }
276 
277 static HRESULT WINAPI ddraw_surface3_QueryInterface(IDirectDrawSurface3 *iface, REFIID riid, void **object)
278 {
279  struct ddraw_surface *surface = impl_from_IDirectDrawSurface3(iface);
280 
281  TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
282 
284 }
285 
286 static HRESULT WINAPI ddraw_surface2_QueryInterface(IDirectDrawSurface2 *iface, REFIID riid, void **object)
287 {
288  struct ddraw_surface *surface = impl_from_IDirectDrawSurface2(iface);
289 
290  TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
291 
293 }
294 
295 static HRESULT WINAPI ddraw_surface1_QueryInterface(IDirectDrawSurface *iface, REFIID riid, void **object)
296 {
297  struct ddraw_surface *surface = impl_from_IDirectDrawSurface(iface);
298 
299  TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
300 
302 }
303 
304 static HRESULT WINAPI ddraw_gamma_control_QueryInterface(IDirectDrawGammaControl *iface,
305  REFIID riid, void **object)
306 {
307  struct ddraw_surface *surface = impl_from_IDirectDrawGammaControl(iface);
308 
309  TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
310 
312 }
313 
314 static HRESULT WINAPI d3d_texture2_QueryInterface(IDirect3DTexture2 *iface, REFIID riid, void **object)
315 {
316  struct ddraw_surface *surface = impl_from_IDirect3DTexture2(iface);
317 
318  TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
319 
321 }
322 
323 static HRESULT WINAPI d3d_texture1_QueryInterface(IDirect3DTexture *iface, REFIID riid, void **object)
324 {
325  struct ddraw_surface *surface = impl_from_IDirect3DTexture(iface);
326 
327  TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
328 
330 }
331 
332 static void ddraw_surface_add_iface(struct ddraw_surface *surface)
333 {
335  TRACE("%p increasing iface count to %u.\n", surface, iface_count);
336 
337  if (iface_count == 1)
338  {
339  if (surface->ifaceToRelease)
340  IUnknown_AddRef(surface->ifaceToRelease);
342  if (surface->wined3d_rtv)
346  }
347 }
348 
349 /*****************************************************************************
350  * IDirectDrawSurface7::AddRef
351  *
352  * A normal addref implementation
353  *
354  * Returns:
355  * The new refcount
356  *
357  *****************************************************************************/
359 {
361  ULONG refcount = InterlockedIncrement(&This->ref7);
362 
363  TRACE("iface %p increasing refcount to %u.\n", iface, refcount);
364 
365  if (refcount == 1)
366  {
368  }
369 
370  return refcount;
371 }
372 
373 static ULONG WINAPI ddraw_surface4_AddRef(IDirectDrawSurface4 *iface)
374 {
376  ULONG refcount = InterlockedIncrement(&This->ref4);
377 
378  TRACE("iface %p increasing refcount to %u.\n", iface, refcount);
379 
380  if (refcount == 1)
381  {
383  }
384 
385  return refcount;
386 }
387 
388 static ULONG WINAPI ddraw_surface3_AddRef(IDirectDrawSurface3 *iface)
389 {
391  ULONG refcount = InterlockedIncrement(&This->ref3);
392 
393  TRACE("iface %p increasing refcount to %u.\n", iface, refcount);
394 
395  if (refcount == 1)
396  {
398  }
399 
400  return refcount;
401 }
402 
403 static ULONG WINAPI ddraw_surface2_AddRef(IDirectDrawSurface2 *iface)
404 {
406  ULONG refcount = InterlockedIncrement(&This->ref2);
407 
408  TRACE("iface %p increasing refcount to %u.\n", iface, refcount);
409 
410  if (refcount == 1)
411  {
413  }
414 
415  return refcount;
416 }
417 
418 static ULONG WINAPI ddraw_surface1_AddRef(IDirectDrawSurface *iface)
419 {
421  ULONG refcount = InterlockedIncrement(&This->ref1);
422 
423  TRACE("iface %p increasing refcount to %u.\n", iface, refcount);
424 
425  if (refcount == 1)
426  {
428  }
429 
430  return refcount;
431 }
432 
433 static ULONG WINAPI ddraw_gamma_control_AddRef(IDirectDrawGammaControl *iface)
434 {
436  ULONG refcount = InterlockedIncrement(&This->gamma_count);
437 
438  TRACE("iface %p increasing refcount to %u.\n", iface, refcount);
439 
440  if (refcount == 1)
441  {
443  }
444 
445  return refcount;
446 }
447 
448 static ULONG WINAPI d3d_texture2_AddRef(IDirect3DTexture2 *iface)
449 {
450  struct ddraw_surface *surface = impl_from_IDirect3DTexture2(iface);
451 
452  TRACE("iface %p.\n", iface);
453 
454  return IUnknown_AddRef(surface->texture_outer);
455 }
456 
457 static ULONG WINAPI d3d_texture1_AddRef(IDirect3DTexture *iface)
458 {
459  struct ddraw_surface *surface = impl_from_IDirect3DTexture(iface);
460 
461  TRACE("iface %p.\n", iface);
462 
463  return IUnknown_AddRef(surface->texture_outer);
464 }
465 
466 static HRESULT ddraw_surface_set_palette(struct ddraw_surface *surface, IDirectDrawPalette *palette)
467 {
469  struct ddraw_palette *prev;
470 
471  TRACE("iface %p, palette %p.\n", surface, palette);
472 
473  if (palette_impl && palette_impl->flags & DDPCAPS_ALPHA
474  && !(surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_TEXTURE))
475  {
476  WARN("Alpha palette set on non-texture surface, returning DDERR_INVALIDSURFACETYPE.\n");
478  }
479 
482 
484 
485  prev = surface->palette;
487  {
488  if (prev)
489  prev->flags &= ~DDPCAPS_PRIMARYSURFACE;
490  if (palette_impl)
491  palette_impl->flags |= DDPCAPS_PRIMARYSURFACE;
492  wined3d_swapchain_set_palette(surface->ddraw->wined3d_swapchain,
493  palette_impl ? palette_impl->wined3d_palette : NULL);
495  }
496  if (palette_impl)
497  IDirectDrawPalette_AddRef(&palette_impl->IDirectDrawPalette_iface);
498  if (prev)
499  IDirectDrawPalette_Release(&prev->IDirectDrawPalette_iface);
500  surface->palette = palette_impl;
501 
503 
504  return DD_OK;
505 }
506 
507 static void ddraw_surface_cleanup(struct ddraw_surface *surface)
508 {
509  struct ddraw_surface *surf;
510  UINT i;
511 
512  TRACE("surface %p.\n", surface);
513 
514  /* The refcount test shows that the palette is detached when the surface
515  * is destroyed. */
517 
518  /* Loop through all complex attached surfaces and destroy them.
519  *
520  * Yet again, only the root can have more than one complexly attached
521  * surface, all the others have a total of one. */
522  for (i = 0; i < MAX_COMPLEX_ATTACHED; ++i)
523  {
524  if (!surface->complex_array[i])
525  break;
526 
527  surf = surface->complex_array[i];
528  surface->complex_array[i] = NULL;
529  if (!surf->is_complex_root)
530  ddraw_surface_cleanup(surf);
531  }
532 
533  if (surface->device1)
534  IUnknown_Release(&surface->device1->IUnknown_inner);
535 
536  if (surface->iface_count > 1)
537  {
538  /* This can happen when a complex surface is destroyed, because the
539  * 2nd surface was addref()ed when the app called
540  * GetAttachedSurface(). */
541  WARN("Destroying surface %p with refcounts 7: %u 4: %u 3: %u 2: %u 1: %u.\n",
542  surface, surface->ref7, surface->ref4, surface->ref3, surface->ref2, surface->ref1);
543  }
544 
545  if (surface->wined3d_rtv)
548 }
549 
551 {
553 
554  /* Prevent the surface from being destroyed if it's still attached to
555  * another surface. It will be destroyed when the root is destroyed. */
556  if (This->iface_count == 1 && This->attached_iface)
557  IUnknown_AddRef(This->attached_iface);
558  iface_count = InterlockedDecrement(&This->iface_count);
559 
560  TRACE("%p decreasing iface count to %u.\n", This, iface_count);
561 
562  if (iface_count == 0)
563  {
564  struct ddraw_texture *texture = wined3d_texture_get_parent(This->wined3d_texture);
565  struct wined3d_device *wined3d_device = texture->wined3d_device;
566  IUnknown *release_iface = This->ifaceToRelease;
567 
568  /* Complex attached surfaces are destroyed implicitly when the root is released */
570  if(!This->is_complex_root)
571  {
572  WARN("(%p) Attempt to destroy a surface that is not a complex root\n", This);
574  return iface_count;
575  }
578 
579  if (release_iface)
580  IUnknown_Release(release_iface);
581  /* Release the device only after anything that may reference it (the
582  * wined3d texture and rendertarget view in particular) is released. */
584  }
585 
586  return iface_count;
587 }
588 
589 /*****************************************************************************
590  * IDirectDrawSurface7::Release
591  *
592  * Reduces the surface's refcount by 1. If the refcount falls to 0, the
593  * surface is destroyed.
594  *
595  * Destroying the surface is a bit tricky. For the connection between
596  * WineD3DSurfaces and DirectDrawSurfaces see IDirectDraw7::CreateSurface
597  * It has a nice graph explaining the connection.
598  *
599  * What happens here is basically this:
600  * When a surface is destroyed, its WineD3DSurface is released,
601  * and the refcount of the DirectDraw interface is reduced by 1. If it has
602  * complex surfaces attached to it, then these surfaces are destroyed too,
603  * regardless of their refcount. If any surface being destroyed has another
604  * surface attached to it (with a "soft" attachment, not complex), then
605  * this surface is detached with DeleteAttachedSurface.
606  *
607  * When the surface is a texture, the WineD3DTexture is released.
608  * If the surface is the Direct3D render target, then the D3D
609  * capabilities of the WineD3DDevice are uninitialized, which causes the
610  * swapchain to be released.
611  *
612  * When a complex sublevel falls to ref zero, then this is ignored.
613  *
614  * Returns:
615  * The new refcount
616  *
617  *****************************************************************************/
619 {
621  ULONG refcount = InterlockedDecrement(&This->ref7);
622 
623  TRACE("iface %p decreasing refcount to %u.\n", iface, refcount);
624 
625  if (refcount == 0)
626  {
628  }
629 
630  return refcount;
631 }
632 
633 static ULONG WINAPI ddraw_surface4_Release(IDirectDrawSurface4 *iface)
634 {
636  ULONG refcount = InterlockedDecrement(&This->ref4);
637 
638  TRACE("iface %p decreasing refcount to %u.\n", iface, refcount);
639 
640  if (refcount == 0)
641  {
643  }
644 
645  return refcount;
646 }
647 
648 static ULONG WINAPI ddraw_surface3_Release(IDirectDrawSurface3 *iface)
649 {
651  ULONG refcount = InterlockedDecrement(&This->ref3);
652 
653  TRACE("iface %p decreasing refcount to %u.\n", iface, refcount);
654 
655  if (refcount == 0)
656  {
658  }
659 
660  return refcount;
661 }
662 
663 static ULONG WINAPI ddraw_surface2_Release(IDirectDrawSurface2 *iface)
664 {
666  ULONG refcount = InterlockedDecrement(&This->ref2);
667 
668  TRACE("iface %p decreasing refcount to %u.\n", iface, refcount);
669 
670  if (refcount == 0)
671  {
673  }
674 
675  return refcount;
676 }
677 
678 static ULONG WINAPI ddraw_surface1_Release(IDirectDrawSurface *iface)
679 {
681  ULONG refcount = InterlockedDecrement(&This->ref1);
682 
683  TRACE("iface %p decreasing refcount to %u.\n", iface, refcount);
684 
685  if (refcount == 0)
686  {
688  }
689 
690  return refcount;
691 }
692 
693 static ULONG WINAPI ddraw_gamma_control_Release(IDirectDrawGammaControl *iface)
694 {
696  ULONG refcount = InterlockedDecrement(&This->gamma_count);
697 
698  TRACE("iface %p decreasing refcount to %u.\n", iface, refcount);
699 
700  if (refcount == 0)
701  {
703  }
704 
705  return refcount;
706 }
707 
708 static ULONG WINAPI d3d_texture2_Release(IDirect3DTexture2 *iface)
709 {
710  struct ddraw_surface *surface = impl_from_IDirect3DTexture2(iface);
711 
712  TRACE("iface %p.\n", iface);
713 
714  return IUnknown_Release(surface->texture_outer);
715 }
716 
717 static ULONG WINAPI d3d_texture1_Release(IDirect3DTexture *iface)
718 {
719  struct ddraw_surface *surface = impl_from_IDirect3DTexture(iface);
720 
721  TRACE("iface %p.\n", iface);
722 
723  return IUnknown_Release(surface->texture_outer);
724 }
725 
726 /*****************************************************************************
727  * IDirectDrawSurface7::GetAttachedSurface
728  *
729  * Returns an attached surface with the requested caps. Surface attachment
730  * and complex surfaces are not clearly described by the MSDN or sdk,
731  * so this method is tricky and likely to contain problems.
732  * This implementation searches the complex list first, then the
733  * attachment chain.
734  *
735  * The chains are searched from This down to the last surface in the chain,
736  * not from the first element in the chain. The first surface found is
737  * returned. The MSDN says that this method fails if more than one surface
738  * matches the caps, but it is not sure if that is right. The attachment
739  * structure may not even allow two matching surfaces.
740  *
741  * The found surface is AddRef-ed before it is returned.
742  *
743  * Params:
744  * Caps: Pointer to a DDCAPS2 structure describing the caps asked for
745  * Surface: Address to store the found surface
746  *
747  * Returns:
748  * DD_OK on success
749  * DDERR_INVALIDPARAMS if Caps or Surface is NULL
750  * DDERR_NOTFOUND if no surface was found
751  *
752  *****************************************************************************/
754  DDSCAPS2 *Caps, IDirectDrawSurface7 **Surface)
755 {
757  struct ddraw_surface *surf;
758  DDSCAPS2 our_caps;
759  int i;
760 
761  TRACE("iface %p, caps %p, attachment %p.\n", iface, Caps, Surface);
762 
764 
765  if(This->version < 7)
766  {
767  /* Earlier dx apps put garbage into these members, clear them */
768  our_caps.dwCaps = Caps->dwCaps;
769  our_caps.dwCaps2 = 0;
770  our_caps.dwCaps3 = 0;
771  our_caps.u1.dwCaps4 = 0;
772  }
773  else
774  {
775  our_caps = *Caps;
776  }
777 
778  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 */
779 
780  for(i = 0; i < MAX_COMPLEX_ATTACHED; i++)
781  {
782  surf = This->complex_array[i];
783  if(!surf) break;
784 
785  TRACE("Surface: (%p) caps: %#x, %#x, %#x, %#x.\n", surf,
789  surf->surface_desc.ddsCaps.u1.dwCaps4);
790 
791  if (((surf->surface_desc.ddsCaps.dwCaps & our_caps.dwCaps) == our_caps.dwCaps) &&
792  ((surf->surface_desc.ddsCaps.dwCaps2 & our_caps.dwCaps2) == our_caps.dwCaps2)) {
793 
794  /* MSDN: "This method fails if more than one surface is attached
795  * that matches the capabilities requested."
796  *
797  * Not sure how to test this.
798  */
799 
800  TRACE("(%p): Returning surface %p\n", This, surf);
801  *Surface = &surf->IDirectDrawSurface7_iface;
802  ddraw_surface7_AddRef(*Surface);
804 
805  return DD_OK;
806  }
807  }
808 
809  /* Next, look at the attachment chain */
810  surf = This;
811 
812  while( (surf = surf->next_attached) )
813  {
814  TRACE("Surface: (%p) caps: %#x, %#x, %#x, %#x.\n", surf,
818  surf->surface_desc.ddsCaps.u1.dwCaps4);
819 
820  if (((surf->surface_desc.ddsCaps.dwCaps & our_caps.dwCaps) == our_caps.dwCaps) &&
821  ((surf->surface_desc.ddsCaps.dwCaps2 & our_caps.dwCaps2) == our_caps.dwCaps2)) {
822 
823  TRACE("(%p): Returning surface %p\n", This, surf);
824  *Surface = &surf->IDirectDrawSurface7_iface;
825  ddraw_surface7_AddRef(*Surface);
827  return DD_OK;
828  }
829  }
830 
831  TRACE("(%p) Didn't find a valid surface\n", This);
832 
834 
835  *Surface = NULL;
836  return DDERR_NOTFOUND;
837 }
838 
839 static HRESULT WINAPI ddraw_surface4_GetAttachedSurface(IDirectDrawSurface4 *iface,
840  DDSCAPS2 *caps, IDirectDrawSurface4 **attachment)
841 {
842  struct ddraw_surface *surface = impl_from_IDirectDrawSurface4(iface);
843  struct ddraw_surface *attachment_impl;
844  IDirectDrawSurface7 *attachment7;
845  HRESULT hr;
846 
847  TRACE("iface %p, caps %p, attachment %p.\n", iface, caps, attachment);
848 
850  caps, &attachment7);
851  if (FAILED(hr))
852  {
853  *attachment = NULL;
854  return hr;
855  }
856  attachment_impl = impl_from_IDirectDrawSurface7(attachment7);
857  *attachment = &attachment_impl->IDirectDrawSurface4_iface;
859  ddraw_surface7_Release(attachment7);
860 
861  return hr;
862 }
863 
864 static HRESULT WINAPI ddraw_surface3_GetAttachedSurface(IDirectDrawSurface3 *iface,
865  DDSCAPS *caps, IDirectDrawSurface3 **attachment)
866 {
867  struct ddraw_surface *surface = impl_from_IDirectDrawSurface3(iface);
868  struct ddraw_surface *attachment_impl;
869  IDirectDrawSurface7 *attachment7;
870  DDSCAPS2 caps2;
871  HRESULT hr;
872 
873  TRACE("iface %p, caps %p, attachment %p.\n", iface, caps, attachment);
874 
875  caps2.dwCaps = caps->dwCaps;
876  caps2.dwCaps2 = 0;
877  caps2.dwCaps3 = 0;
878  caps2.u1.dwCaps4 = 0;
879 
881  &caps2, &attachment7);
882  if (FAILED(hr))
883  {
884  *attachment = NULL;
885  return hr;
886  }
887  attachment_impl = impl_from_IDirectDrawSurface7(attachment7);
888  *attachment = &attachment_impl->IDirectDrawSurface3_iface;
890  ddraw_surface7_Release(attachment7);
891 
892  return hr;
893 }
894 
895 static HRESULT WINAPI ddraw_surface2_GetAttachedSurface(IDirectDrawSurface2 *iface,
896  DDSCAPS *caps, IDirectDrawSurface2 **attachment)
897 {
898  struct ddraw_surface *surface = impl_from_IDirectDrawSurface2(iface);
899  struct ddraw_surface *attachment_impl;
900  IDirectDrawSurface7 *attachment7;
901  DDSCAPS2 caps2;
902  HRESULT hr;
903 
904  TRACE("iface %p, caps %p, attachment %p.\n", iface, caps, attachment);
905 
906  caps2.dwCaps = caps->dwCaps;
907  caps2.dwCaps2 = 0;
908  caps2.dwCaps3 = 0;
909  caps2.u1.dwCaps4 = 0;
910 
912  &caps2, &attachment7);
913  if (FAILED(hr))
914  {
915  *attachment = NULL;
916  return hr;
917  }
918  attachment_impl = impl_from_IDirectDrawSurface7(attachment7);
919  *attachment = &attachment_impl->IDirectDrawSurface2_iface;
921  ddraw_surface7_Release(attachment7);
922 
923  return hr;
924 }
925 
926 static HRESULT WINAPI ddraw_surface1_GetAttachedSurface(IDirectDrawSurface *iface,
927  DDSCAPS *caps, IDirectDrawSurface **attachment)
928 {
929  struct ddraw_surface *surface = impl_from_IDirectDrawSurface(iface);
930  struct ddraw_surface *attachment_impl;
931  IDirectDrawSurface7 *attachment7;
932  DDSCAPS2 caps2;
933  HRESULT hr;
934 
935  TRACE("iface %p, caps %p, attachment %p.\n", iface, caps, attachment);
936 
937  caps2.dwCaps = caps->dwCaps;
938  caps2.dwCaps2 = 0;
939  caps2.dwCaps3 = 0;
940  caps2.u1.dwCaps4 = 0;
941 
943  &caps2, &attachment7);
944  if (FAILED(hr))
945  {
946  *attachment = NULL;
947  return hr;
948  }
949  attachment_impl = impl_from_IDirectDrawSurface7(attachment7);
950  *attachment = &attachment_impl->IDirectDrawSurface_iface;
952  ddraw_surface7_Release(attachment7);
953 
954  return hr;
955 }
956 
957 /*****************************************************************************
958  * IDirectDrawSurface7::Lock
959  *
960  * Locks the surface and returns a pointer to the surface's memory
961  *
962  * Params:
963  * Rect: Rectangle to lock. If NULL, the whole surface is locked
964  * DDSD: Pointer to a DDSURFACEDESC2 which shall receive the surface's desc.
965  * Flags: Locking flags, e.g Read only or write only
966  * h: An event handle that's not used and must be NULL
967  *
968  * Returns:
969  * DD_OK on success
970  * DDERR_INVALIDPARAMS if DDSD is NULL
971  *
972  *****************************************************************************/
973 static HRESULT surface_lock(struct ddraw_surface *surface,
974  RECT *rect, DDSURFACEDESC2 *surface_desc, unsigned int surface_desc_size,
975  DWORD flags, HANDLE h)
976 {
977  struct wined3d_map_desc map_desc;
978  struct wined3d_box box;
979  HRESULT hr = DD_OK;
980 
981  TRACE("surface %p, rect %s, surface_desc %p, surface_desc_size %u, flags %#x, h %p.\n",
982  surface, wine_dbgstr_rect(rect), surface_desc, surface_desc_size, flags, h);
983 
984  /* surface->surface_desc.dwWidth and dwHeight are changeable, thus lock */
986 
987  /* Should I check for the handle to be NULL?
988  *
989  * The DDLOCK flags and the D3DLOCK flags are equal
990  * for the supported values. The others are ignored by WineD3D
991  */
992 
993  /* Windows zeroes this if the rect is invalid */
994  surface_desc->lpSurface = NULL;
995 
996  if (rect)
997  {
998  if ((rect->left < 0) || (rect->top < 0)
999  || (rect->left > rect->right) || (rect->right > surface->surface_desc.dwWidth)
1000  || (rect->top > rect->bottom) || (rect->bottom > surface->surface_desc.dwHeight))
1001  {
1002  WARN("Trying to lock an invalid rectangle, returning DDERR_INVALIDPARAMS\n");
1004  return DDERR_INVALIDPARAMS;
1005  }
1006  wined3d_box_set(&box, rect->left, rect->top, rect->right, rect->bottom, 0, 1);
1007  }
1008 
1010  hr = ddraw_surface_update_frontbuffer(surface, rect, TRUE, 0);
1011  if (SUCCEEDED(hr))
1013  surface->sub_resource_idx, &map_desc, rect ? &box : NULL,
1015  if (FAILED(hr))
1016  {
1018  switch(hr)
1019  {
1020  /* D3D8 and D3D9 return the general D3DERR_INVALIDCALL error, but ddraw has a more
1021  * specific error. But since wined3d returns that error in this only occasion,
1022  * keep d3d8 and d3d9 free from the return value override. There are many different
1023  * places where d3d8/9 would have to catch the DDERR_SURFACEBUSY, it is much easier
1024  * to do it in one place in ddraw.
1025  */
1027  default: return hr;
1028  }
1029  }
1030 
1032  {
1033  if (flags & DDLOCK_READONLY)
1034  SetRectEmpty(&surface->ddraw->primary_lock);
1035  else if (rect)
1036  surface->ddraw->primary_lock = *rect;
1037  else
1038  SetRect(&surface->ddraw->primary_lock, 0, 0, surface->surface_desc.dwWidth, surface->surface_desc.dwHeight);
1039  }
1040 
1041  /* Windows does not set DDSD_LPSURFACE on locked surfaces. */
1042  DD_STRUCT_COPY_BYSIZE_(surface_desc, &surface->surface_desc, surface_desc_size, surface->surface_desc.dwSize);
1043  surface_desc->lpSurface = map_desc.data;
1044 
1045  TRACE("locked surface returning description :\n");
1046  if (TRACE_ON(ddraw))
1047  DDRAW_dump_surface_desc(surface_desc);
1048 
1050 
1051  return DD_OK;
1052 }
1053 
1055  const DDSURFACEDESC *desc, unsigned int *size)
1056 {
1057  if (!desc)
1058  return FALSE;
1059 
1060  if (desc->dwSize == sizeof(DDSURFACEDESC) || desc->dwSize == sizeof(DDSURFACEDESC2))
1061  {
1062  *size = desc->dwSize;
1063  return TRUE;
1064  }
1065 
1066  if (surface->version == 7
1069  {
1070  if (desc->dwSize >= sizeof(DDSURFACEDESC2))
1071  *size = sizeof(DDSURFACEDESC2);
1072  else
1073  *size = sizeof(DDSURFACEDESC);
1074  return TRUE;
1075  }
1076 
1077  WARN("Invalid structure size %u.\n", desc->dwSize);
1078  return FALSE;
1079 }
1080 
1082  RECT *rect, DDSURFACEDESC2 *surface_desc, DWORD flags, HANDLE h)
1083 {
1084  struct ddraw_surface *surface = impl_from_IDirectDrawSurface7(iface);
1085  unsigned int surface_desc_size;
1086 
1087  TRACE("iface %p, rect %s, surface_desc %p, flags %#x, h %p.\n",
1089 
1090  if (!surface_validate_lock_desc(surface, (DDSURFACEDESC *)surface_desc, &surface_desc_size))
1091  return DDERR_INVALIDPARAMS;
1092 
1093  return surface_lock(surface, rect, surface_desc, surface_desc_size, flags, h);
1094 }
1095 
1096 static HRESULT WINAPI ddraw_surface4_Lock(IDirectDrawSurface4 *iface, RECT *rect,
1098 {
1099  struct ddraw_surface *surface = impl_from_IDirectDrawSurface4(iface);
1100  unsigned int surface_desc_size;
1101 
1102  TRACE("iface %p, rect %s, surface_desc %p, flags %#x, h %p.\n",
1104 
1105  if (!surface_validate_lock_desc(surface, (DDSURFACEDESC *)surface_desc, &surface_desc_size))
1106  return DDERR_INVALIDPARAMS;
1107 
1108  return surface_lock(surface, rect, surface_desc, surface_desc_size, flags, h);
1109 }
1110 
1111 static HRESULT WINAPI ddraw_surface3_Lock(IDirectDrawSurface3 *iface, RECT *rect,
1113 {
1114  struct ddraw_surface *surface = impl_from_IDirectDrawSurface3(iface);
1115  unsigned int surface_desc_size;
1116  DDSURFACEDESC2 surface_desc2;
1117  HRESULT hr;
1118 
1119  TRACE("iface %p, rect %s, surface_desc %p, flags %#x, h %p.\n",
1121 
1122  if (!surface_validate_lock_desc(surface, surface_desc, &surface_desc_size))
1123  return DDERR_INVALIDPARAMS;
1124 
1125  surface_desc2.dwSize = surface_desc->dwSize;
1126  surface_desc2.dwFlags = 0;
1127  hr = surface_lock(surface, rect, &surface_desc2, surface_desc_size, flags, h);
1128  DDSD2_to_DDSD(&surface_desc2, surface_desc);
1129  surface_desc->dwSize = surface_desc2.dwSize;
1130  return hr;
1131 }
1132 
1133 static HRESULT WINAPI ddraw_surface2_Lock(IDirectDrawSurface2 *iface, RECT *rect,
1135 {
1136  struct ddraw_surface *surface = impl_from_IDirectDrawSurface2(iface);
1137  unsigned int surface_desc_size;
1138  DDSURFACEDESC2 surface_desc2;
1139  HRESULT hr;
1140 
1141  TRACE("iface %p, rect %s, surface_desc %p, flags %#x, h %p.\n",
1143 
1144  if (!surface_validate_lock_desc(surface, surface_desc, &surface_desc_size))
1145  return DDERR_INVALIDPARAMS;
1146 
1147  surface_desc2.dwSize = surface_desc->dwSize;
1148  surface_desc2.dwFlags = 0;
1149  hr = surface_lock(surface, rect, &surface_desc2, surface_desc_size, flags, h);
1150  DDSD2_to_DDSD(&surface_desc2, surface_desc);
1151  surface_desc->dwSize = surface_desc2.dwSize;
1152  return hr;
1153 }
1154 
1155 static HRESULT WINAPI ddraw_surface1_Lock(IDirectDrawSurface *iface, RECT *rect,
1157 {
1158  struct ddraw_surface *surface = impl_from_IDirectDrawSurface(iface);
1159  unsigned int surface_desc_size;
1160  DDSURFACEDESC2 surface_desc2;
1161  HRESULT hr;
1162 
1163  TRACE("iface %p, rect %s, surface_desc %p, flags %#x, h %p.\n",
1165 
1166  if (!surface_validate_lock_desc(surface, surface_desc, &surface_desc_size))
1167  return DDERR_INVALIDPARAMS;
1168 
1169  surface_desc2.dwSize = surface_desc->dwSize;
1170  surface_desc2.dwFlags = 0;
1171  hr = surface_lock(surface, rect, &surface_desc2, surface_desc_size, flags, h);
1172  DDSD2_to_DDSD(&surface_desc2, surface_desc);
1173  surface_desc->dwSize = surface_desc2.dwSize;
1174  return hr;
1175 }
1176 
1177 /*****************************************************************************
1178  * IDirectDrawSurface7::Unlock
1179  *
1180  * Unlocks an locked surface
1181  *
1182  * Params:
1183  * Rect: Not used by this implementation
1184  *
1185  * Returns:
1186  * D3D_OK on success, error code otherwise.
1187  *
1188  *****************************************************************************/
1190 {
1191  struct ddraw_surface *surface = impl_from_IDirectDrawSurface7(iface);
1192  HRESULT hr;
1193 
1194  TRACE("iface %p, rect %s.\n", iface, wine_dbgstr_rect(pRect));
1195 
1199  hr = ddraw_surface_update_frontbuffer(surface, &surface->ddraw->primary_lock, FALSE, 0);
1201 
1202  return hr;
1203 }
1204 
1205 static HRESULT WINAPI DECLSPEC_HOTPATCH ddraw_surface4_Unlock(IDirectDrawSurface4 *iface, RECT *pRect)
1206 {
1207  struct ddraw_surface *surface = impl_from_IDirectDrawSurface4(iface);
1208 
1209  TRACE("iface %p, rect %p.\n", iface, pRect);
1210 
1211  return ddraw_surface7_Unlock(&surface->IDirectDrawSurface7_iface, pRect);
1212 }
1213 
1214 static HRESULT WINAPI DECLSPEC_HOTPATCH ddraw_surface3_Unlock(IDirectDrawSurface3 *iface, void *data)
1215 {
1216  struct ddraw_surface *surface = impl_from_IDirectDrawSurface3(iface);
1217 
1218  TRACE("iface %p, data %p.\n", iface, data);
1219 
1220  /* data might not be the LPRECT of later versions, so drop it. */
1222 }
1223 
1224 static HRESULT WINAPI DECLSPEC_HOTPATCH ddraw_surface2_Unlock(IDirectDrawSurface2 *iface, void *data)
1225 {
1226  struct ddraw_surface *surface = impl_from_IDirectDrawSurface2(iface);
1227 
1228  TRACE("iface %p, data %p.\n", iface, data);
1229 
1230  /* data might not be the LPRECT of later versions, so drop it. */
1232 }
1233 
1234 static HRESULT WINAPI DECLSPEC_HOTPATCH ddraw_surface1_Unlock(IDirectDrawSurface *iface, void *data)
1235 {
1236  struct ddraw_surface *surface = impl_from_IDirectDrawSurface(iface);
1237 
1238  TRACE("iface %p, data %p.\n", iface, data);
1239 
1240  /* data might not be the LPRECT of later versions, so drop it. */
1242 }
1243 
1245 {
1246  if (flags & DDFLIP_NOVSYNC)
1247  return 0;
1248 
1250  {
1251  case DDFLIP_INTERVAL2:
1252  return 2;
1253  case DDFLIP_INTERVAL3:
1254  return 3;
1255  case DDFLIP_INTERVAL4:
1256  return 4;
1257  default:
1258  return 1;
1259  }
1260 }
1261 
1264 {
1265  struct ddraw_surface *dst_impl = impl_from_IDirectDrawSurface7(iface);
1267  struct wined3d_rendertarget_view *tmp_rtv, *src_rtv, *rtv;
1268  struct ddraw_texture *ddraw_texture, *prev_ddraw_texture;
1269  DDSCAPS2 caps = {DDSCAPS_FLIP, 0, 0, {0}};
1270  struct wined3d_texture *texture;
1272  HRESULT hr;
1273 
1274  TRACE("iface %p, src %p, flags %#x.\n", iface, src, flags);
1275 
1276  if (src == iface || !(dst_impl->surface_desc.ddsCaps.dwCaps & (DDSCAPS_FRONTBUFFER | DDSCAPS_OVERLAY)))
1277  return DDERR_NOTFLIPPABLE;
1278 
1279  if (IDirectDrawSurface7_IsLost(iface) == DDERR_SURFACELOST)
1280  return DDERR_SURFACELOST;
1281 
1283 
1285  && !(dst_impl->ddraw->cooperative_level & DDSCL_EXCLUSIVE))
1286  {
1287  WARN("Not in exclusive mode.\n");
1289  return DDERR_NOEXCLUSIVEMODE;
1290  }
1291 
1292  tmp_rtv = ddraw_surface_get_rendertarget_view(dst_impl);
1293  if (dst_impl->sub_resource_idx)
1294  ERR("Invalid sub-resource index %u on surface %p.\n", dst_impl->sub_resource_idx, dst_impl);
1295  texture = dst_impl->wined3d_texture;
1296  rtv = wined3d_device_get_rendertarget_view(dst_impl->ddraw->wined3d_device, 0);
1298 
1299  if (src_impl)
1300  {
1301  for (current = iface; current != src;)
1302  {
1304  {
1305  WARN("Surface %p is not on the same flip chain as surface %p.\n", src, iface);
1307  return DDERR_NOTFLIPPABLE;
1308  }
1310  if (current == iface)
1311  {
1312  WARN("Surface %p is not on the same flip chain as surface %p.\n", src, iface);
1314  return DDERR_NOTFLIPPABLE;
1315  }
1316  }
1317 
1318  src_rtv = ddraw_surface_get_rendertarget_view(src_impl);
1319  if (rtv == dst_impl->wined3d_rtv)
1320  wined3d_device_set_rendertarget_view(dst_impl->ddraw->wined3d_device, 0, src_rtv, FALSE);
1321  wined3d_rendertarget_view_set_parent(src_rtv, dst_impl);
1322  dst_impl->wined3d_rtv = src_rtv;
1324  prev_ddraw_texture = wined3d_texture_get_parent(src_impl->wined3d_texture);
1326  if (src_impl->sub_resource_idx)
1327  ERR("Invalid sub-resource index %u on surface %p.\n", src_impl->sub_resource_idx, src_impl);
1328  dst_impl->wined3d_texture = src_impl->wined3d_texture;
1329  ddraw_texture = prev_ddraw_texture;
1330  }
1331  else
1332  {
1333  for (current = iface;;)
1334  {
1336  {
1337  ERR("Can't find a flip target\n");
1339  return DDERR_NOTFLIPPABLE; /* Unchecked */
1340  }
1342  if (current == iface)
1343  {
1344  dst_impl = impl_from_IDirectDrawSurface7(iface);
1345  break;
1346  }
1347 
1349  src_rtv = ddraw_surface_get_rendertarget_view(src_impl);
1350  if (rtv == dst_impl->wined3d_rtv)
1351  wined3d_device_set_rendertarget_view(dst_impl->ddraw->wined3d_device, 0, src_rtv, FALSE);
1352  wined3d_rendertarget_view_set_parent(src_rtv, dst_impl);
1353  dst_impl->wined3d_rtv = src_rtv;
1355  prev_ddraw_texture = wined3d_texture_get_parent(src_impl->wined3d_texture);
1357  ddraw_texture = prev_ddraw_texture;
1358  if (src_impl->sub_resource_idx)
1359  ERR("Invalid sub-resource index %u on surface %p.\n", src_impl->sub_resource_idx, src_impl);
1360  dst_impl->wined3d_texture = src_impl->wined3d_texture;
1361  dst_impl = src_impl;
1362  }
1363  }
1364 
1365  /* We don't have to worry about potential texture bindings, since
1366  * flippable surfaces can never be textures. */
1367  if (rtv == src_impl->wined3d_rtv)
1368  wined3d_device_set_rendertarget_view(dst_impl->ddraw->wined3d_device, 0, tmp_rtv, FALSE);
1369  wined3d_rendertarget_view_set_parent(tmp_rtv, src_impl);
1370  src_impl->wined3d_rtv = tmp_rtv;
1373  src_impl->wined3d_texture = texture;
1374 
1376  {
1377  static UINT once;
1378  if (!once++)
1379  FIXME("Ignoring flags %#x.\n", flags);
1380  else
1381  WARN("Ignoring flags %#x.\n", flags);
1382  }
1383 
1386  else
1387  hr = DD_OK;
1388 
1390 
1391  return hr;
1392 }
1393 
1394 static HRESULT WINAPI DECLSPEC_HOTPATCH ddraw_surface4_Flip(IDirectDrawSurface4 *iface,
1395  IDirectDrawSurface4 *src, DWORD flags)
1396 {
1397  struct ddraw_surface *surface = impl_from_IDirectDrawSurface4(iface);
1399 
1400  TRACE("iface %p, src %p, flags %#x.\n", iface, src, flags);
1401 
1403  src_impl ? &src_impl->IDirectDrawSurface7_iface : NULL, flags);
1404 }
1405 
1406 static HRESULT WINAPI DECLSPEC_HOTPATCH ddraw_surface3_Flip(IDirectDrawSurface3 *iface,
1407  IDirectDrawSurface3 *src, DWORD flags)
1408 {
1409  struct ddraw_surface *surface = impl_from_IDirectDrawSurface3(iface);
1411 
1412  TRACE("iface %p, src %p, flags %#x.\n", iface, src, flags);
1413 
1415  src_impl ? &src_impl->IDirectDrawSurface7_iface : NULL, flags);
1416 }
1417 
1418 static HRESULT WINAPI DECLSPEC_HOTPATCH ddraw_surface2_Flip(IDirectDrawSurface2 *iface,
1419  IDirectDrawSurface2 *src, DWORD flags)
1420 {
1421  struct ddraw_surface *surface = impl_from_IDirectDrawSurface2(iface);
1423 
1424  TRACE("iface %p, src %p, flags %#x.\n", iface, src, flags);
1425 
1427  src_impl ? &src_impl->IDirectDrawSurface7_iface : NULL, flags);
1428 }
1429 
1430 static HRESULT WINAPI DECLSPEC_HOTPATCH ddraw_surface1_Flip(IDirectDrawSurface *iface,
1431  IDirectDrawSurface *src, DWORD flags)
1432 {
1433  struct ddraw_surface *surface = impl_from_IDirectDrawSurface(iface);
1435 
1436  TRACE("iface %p, src %p, flags %#x.\n", iface, src, flags);
1437 
1439  src_impl ? &src_impl->IDirectDrawSurface7_iface : NULL, flags);
1440 }
1441 
1442 static HRESULT ddraw_surface_blt(struct ddraw_surface *dst_surface, const RECT *dst_rect,
1443  struct ddraw_surface *src_surface, const RECT *src_rect, DWORD flags, DWORD fill_colour,
1445 {
1446  struct wined3d_device *wined3d_device = dst_surface->ddraw->wined3d_device;
1447  struct wined3d_color colour;
1448  DWORD wined3d_flags;
1449 
1450  if (flags & DDBLT_COLORFILL)
1451  {
1453  dst_surface->palette, fill_colour, &colour))
1454  return DDERR_INVALIDPARAMS;
1455 
1458  dst_rect, WINED3DCLEAR_TARGET, &colour, 0.0f, 0);
1459  }
1460 
1461  if (flags & DDBLT_DEPTHFILL)
1462  {
1464  dst_surface->palette, fill_colour, &colour))
1465  return DDERR_INVALIDPARAMS;
1466 
1469  dst_rect, WINED3DCLEAR_ZBUFFER, NULL, colour.r, 0);
1470  }
1471 
1472  wined3d_flags = flags & ~DDBLT_ASYNC;
1473  if (wined3d_flags & ~WINED3D_BLT_MASK)
1474  {
1475  FIXME("Unhandled flags %#x.\n", flags);
1476  return E_NOTIMPL;
1477  }
1478 
1479  if (!(flags & DDBLT_ASYNC))
1480  wined3d_flags |= WINED3D_BLT_SYNCHRONOUS;
1481 
1482  return wined3d_texture_blt(dst_surface->wined3d_texture, dst_surface->sub_resource_idx, dst_rect,
1483  src_surface->wined3d_texture, src_surface->sub_resource_idx, src_rect, wined3d_flags, fx, filter);
1484 }
1485 
1486 static HRESULT ddraw_surface_blt_clipped(struct ddraw_surface *dst_surface, const RECT *dst_rect_in,
1487  struct ddraw_surface *src_surface, const RECT *src_rect_in, DWORD flags, DWORD fill_colour,
1489 {
1490  RECT src_rect, dst_rect;
1491  float scale_x, scale_y;
1492  const RECT *clip_rect;
1493  UINT clip_list_size;
1494  RGNDATA *clip_list;
1495  HRESULT hr = DD_OK;
1496  UINT i;
1497 
1498  if (!dst_rect_in)
1499  SetRect(&dst_rect, 0, 0, dst_surface->surface_desc.dwWidth,
1500  dst_surface->surface_desc.dwHeight);
1501  else
1502  dst_rect = *dst_rect_in;
1503 
1504  if (IsRectEmpty(&dst_rect))
1505  return DDERR_INVALIDRECT;
1506 
1507  if (src_surface)
1508  {
1509  if (!src_rect_in)
1510  SetRect(&src_rect, 0, 0, src_surface->surface_desc.dwWidth,
1511  src_surface->surface_desc.dwHeight);
1512  else
1513  src_rect = *src_rect_in;
1514 
1515  if (IsRectEmpty(&src_rect))
1516  return DDERR_INVALIDRECT;
1517  }
1518  else
1519  {
1520  SetRectEmpty(&src_rect);
1521  }
1522 
1523  if (!dst_surface->clipper)
1524  {
1525  if (src_surface && src_surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)
1526  hr = ddraw_surface_update_frontbuffer(src_surface, &src_rect, TRUE, 0);
1527  if (SUCCEEDED(hr))
1528  hr = ddraw_surface_blt(dst_surface, &dst_rect, src_surface, &src_rect, flags, fill_colour, fx, filter);
1529  if (SUCCEEDED(hr) && (dst_surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE))
1530  hr = ddraw_surface_update_frontbuffer(dst_surface, &dst_rect, FALSE, 0);
1531 
1532  return hr;
1533  }
1534 
1535  scale_x = (float)(src_rect.right - src_rect.left) / (float)(dst_rect.right - dst_rect.left);
1536  scale_y = (float)(src_rect.bottom - src_rect.top) / (float)(dst_rect.bottom - dst_rect.top);
1537 
1538  if (FAILED(hr = IDirectDrawClipper_GetClipList(&dst_surface->clipper->IDirectDrawClipper_iface,
1539  &dst_rect, NULL, &clip_list_size)))
1540  {
1541  WARN("Failed to get clip list size, hr %#x.\n", hr);
1542  return hr;
1543  }
1544 
1545  if (!(clip_list = heap_alloc(clip_list_size)))
1546  {
1547  WARN("Failed to allocate clip list.\n");
1548  return E_OUTOFMEMORY;
1549  }
1550 
1551  if (FAILED(hr = IDirectDrawClipper_GetClipList(&dst_surface->clipper->IDirectDrawClipper_iface,
1552  &dst_rect, clip_list, &clip_list_size)))
1553  {
1554  WARN("Failed to get clip list, hr %#x.\n", hr);
1555  heap_free(clip_list);
1556  return hr;
1557  }
1558 
1559  clip_rect = (RECT *)clip_list->Buffer;
1560  for (i = 0; i < clip_list->rdh.nCount; ++i)
1561  {
1562  RECT src_rect_clipped = src_rect;
1563 
1564  if (src_surface)
1565  {
1566  src_rect_clipped.left += (LONG)((clip_rect[i].left - dst_rect.left) * scale_x);
1567  src_rect_clipped.top += (LONG)((clip_rect[i].top - dst_rect.top) * scale_y);
1568  src_rect_clipped.right -= (LONG)((dst_rect.right - clip_rect[i].right) * scale_x);
1569  src_rect_clipped.bottom -= (LONG)((dst_rect.bottom - clip_rect[i].bottom) * scale_y);
1570 
1572  {
1573  if (FAILED(hr = ddraw_surface_update_frontbuffer(src_surface, &src_rect_clipped, TRUE, 0)))
1574  break;
1575  }
1576  }
1577 
1578  if (FAILED(hr = ddraw_surface_blt(dst_surface, &clip_rect[i],
1579  src_surface, &src_rect_clipped, flags, fill_colour, fx, filter)))
1580  break;
1581 
1583  {
1584  if (FAILED(hr = ddraw_surface_update_frontbuffer(dst_surface, &clip_rect[i], FALSE, 0)))
1585  break;
1586  }
1587  }
1588 
1589  heap_free(clip_list);
1590  return hr;
1591 }
1592 
1593 /*****************************************************************************
1594  * IDirectDrawSurface7::Blt
1595  *
1596  * Performs a blit on the surface
1597  *
1598  * Params:
1599  * DestRect: Destination rectangle, can be NULL
1600  * SrcSurface: Source surface, can be NULL
1601  * SrcRect: Source rectangle, can be NULL
1602  * Flags: Blt flags
1603  * DDBltFx: Some extended blt parameters, connected to the flags
1604  *
1605  * Returns:
1606  * D3D_OK on success, error code otherwise.
1607  *
1608  *****************************************************************************/
1610  IDirectDrawSurface7 *src_surface, RECT *src_rect, DWORD flags, DDBLTFX *fx)
1611 {
1612  struct ddraw_surface *dst_impl = impl_from_IDirectDrawSurface7(iface);
1613  struct ddraw_surface *src_impl = unsafe_impl_from_IDirectDrawSurface7(src_surface);
1614  struct wined3d_blt_fx wined3d_fx;
1615  DWORD unsupported_flags;
1616  DWORD fill_colour = 0;
1617  HRESULT hr = DD_OK;
1618  DDBLTFX rop_fx;
1619 
1620  TRACE("iface %p, dst_rect %s, src_surface %p, src_rect %s, flags %#x, fx %p.\n",
1621  iface, wine_dbgstr_rect(dst_rect), src_surface, wine_dbgstr_rect(src_rect), flags, fx);
1622 
1623  unsupported_flags = DDBLT_ALPHADEST
1628  | DDBLT_ALPHASRC
1632  | DDBLT_ZBUFFER
1637  if (flags & unsupported_flags)
1638  {
1639  WARN("Ignoring unsupported flags %#x.\n", flags & unsupported_flags);
1640  flags &= ~unsupported_flags;
1641  }
1642 
1643  if ((flags & DDBLT_KEYSRCOVERRIDE) && (!fx || flags & DDBLT_KEYSRC))
1644  {
1645  WARN("Invalid source color key parameters, returning DDERR_INVALIDPARAMS\n");
1646  return DDERR_INVALIDPARAMS;
1647  }
1648 
1649  if ((flags & DDBLT_KEYDESTOVERRIDE) && (!fx || flags & DDBLT_KEYDEST))
1650  {
1651  WARN("Invalid destination color key parameters, returning DDERR_INVALIDPARAMS\n");
1652  return DDERR_INVALIDPARAMS;
1653  }
1654 
1655  if (flags & DDBLT_DDROPS)
1656  {
1657  FIXME("DDBLT_DDROPS not implemented.\n");
1658  if (fx)
1659  FIXME(" rop %#x, pattern %p.\n", fx->dwDDROP, fx->u5.lpDDSPattern);
1660  return DDERR_NORASTEROPHW;
1661  }
1662 
1664 
1666  {
1667  if (flags & DDBLT_ROP)
1668  {
1670  WARN("DDBLT_ROP used with DDBLT_COLORFILL or DDBLT_DEPTHFILL, returning DDERR_INVALIDPARAMS.\n");
1671  return DDERR_INVALIDPARAMS;
1672  }
1673  if (src_impl)
1674  {
1676  WARN("Depth or colorfill is not compatible with source surfaces, returning DDERR_INVALIDPARAMS\n");
1677  return DDERR_INVALIDPARAMS;
1678  }
1679  if (!fx)
1680  {
1682  WARN("Depth or colorfill used with NULL fx, returning DDERR_INVALIDPARAMS.\n");
1683  return DDERR_INVALIDPARAMS;
1684  }
1685 
1687  flags &= ~DDBLT_DEPTHFILL;
1688 
1690  {
1692  WARN("DDBLT_COLORFILL used on a depth buffer, returning DDERR_INVALIDPARAMS.\n");
1693  return DDERR_INVALIDPARAMS;
1694  }
1695  if (!(dst_impl->surface_desc.ddsCaps.dwCaps & DDSCAPS_ZBUFFER) && (flags & DDBLT_DEPTHFILL))
1696  {
1698  WARN("DDBLT_DEPTHFILL used on a color buffer, returning DDERR_INVALIDPARAMS.\n");
1699  return DDERR_INVALIDPARAMS;
1700  }
1701  }
1702 
1703  if (flags & DDBLT_ROP)
1704  {
1705  if (!fx)
1706  {
1708  WARN("DDBLT_ROP used with NULL fx, returning DDERR_INVALIDPARAMS.\n");
1709  return DDERR_INVALIDPARAMS;
1710  }
1711 
1712  if (src_impl && src_rect
1713  && ((ULONG)src_rect->left >= src_rect->right || src_rect->right > src_impl->surface_desc.dwWidth
1714  || (ULONG)src_rect->top >= src_rect->bottom || src_rect->bottom > src_impl->surface_desc.dwHeight))
1715  {
1716  WARN("Invalid source rectangle.\n");
1717  return DDERR_INVALIDRECT;
1718  }
1719 
1720  flags &= ~DDBLT_ROP;
1721  switch (fx->dwROP)
1722  {
1723  case SRCCOPY:
1724  break;
1725 
1726  case WHITENESS:
1727  case BLACKNESS:
1728  rop_fx = *fx;
1729 
1730  if (fx->dwROP == WHITENESS)
1731  rop_fx.u5.dwFillColor = 0xffffffff;
1732  else
1733  rop_fx.u5.dwFillColor = 0;
1734 
1735  if (dst_impl->surface_desc.ddsCaps.dwCaps & DDSCAPS_ZBUFFER)
1737  else
1739 
1740  fx = &rop_fx;
1741  break;
1742 
1743  default:
1745  WARN("Unsupported ROP %#x used, returning DDERR_NORASTEROPHW.\n", fx->dwROP);
1746  return DDERR_NORASTEROPHW;
1747  }
1748  }
1749 
1750  if (!(flags & (DDBLT_COLORFILL | DDBLT_DEPTHFILL)) && !src_impl)
1751  {
1752  WARN("No source surface.\n");
1753  return DDERR_INVALIDPARAMS;
1754  }
1755 
1756  if (flags & DDBLT_KEYSRC && (!src_impl || !(src_impl->surface_desc.dwFlags & DDSD_CKSRCBLT)))
1757  {
1758  WARN("DDBLT_KEYSRC blit without color key in surface, returning DDERR_INVALIDPARAMS\n");
1760  return DDERR_INVALIDPARAMS;
1761  }
1762  if (flags & DDBLT_KEYDEST && !(dst_impl->surface_desc.dwFlags & DDSD_CKDESTBLT))
1763  {
1764  WARN("DDBLT_KEYDEST blit without color key in surface, returning DDERR_INVALIDPARAMS\n");
1766  return DDERR_INVALIDPARAMS;
1767  }
1768 
1769  if (fx)
1770  {
1771  wined3d_fx.fx = fx->dwDDFX;
1772  fill_colour = fx->u5.dwFillColor;
1773  wined3d_fx.dst_color_key.color_space_low_value = fx->ddckDestColorkey.dwColorSpaceLowValue;
1774  wined3d_fx.dst_color_key.color_space_high_value = fx->ddckDestColorkey.dwColorSpaceHighValue;
1775  wined3d_fx.src_color_key.color_space_low_value = fx->ddckSrcColorkey.dwColorSpaceLowValue;
1776  wined3d_fx.src_color_key.color_space_high_value = fx->ddckSrcColorkey.dwColorSpaceHighValue;
1777  }
1778 
1779  hr = ddraw_surface_blt_clipped(dst_impl, dst_rect, src_impl,
1780  src_rect, flags, fill_colour, fx ? &wined3d_fx : NULL, WINED3D_TEXF_LINEAR);
1781 
1783  switch(hr)
1784  {
1786  default: return hr;
1787  }
1788 }
1789 
1790 static HRESULT WINAPI DECLSPEC_HOTPATCH ddraw_surface4_Blt(IDirectDrawSurface4 *iface, RECT *dst_rect,
1791  IDirectDrawSurface4 *src_surface, RECT *src_rect, DWORD flags, DDBLTFX *fx)
1792 {
1795 
1796  TRACE("iface %p, dst_rect %s, src_surface %p, src_rect %s, flags %#x, fx %p.\n",
1797  iface, wine_dbgstr_rect(dst_rect), src_surface, wine_dbgstr_rect(src_rect), flags, fx);
1798 
1799  return ddraw_surface7_Blt(&dst->IDirectDrawSurface7_iface, dst_rect,
1800  src ? &src->IDirectDrawSurface7_iface : NULL, src_rect, flags, fx);
1801 }
1802 
1803 static HRESULT WINAPI DECLSPEC_HOTPATCH ddraw_surface3_Blt(IDirectDrawSurface3 *iface, RECT *dst_rect,
1804  IDirectDrawSurface3 *src_surface, RECT *src_rect, DWORD flags, DDBLTFX *fx)
1805 {
1807  struct ddraw_surface *src_impl = unsafe_impl_from_IDirectDrawSurface3(src_surface);
1808 
1809  TRACE("iface %p, dst_rect %s, src_surface %p, src_rect %s, flags %#x, fx %p.\n",
1810  iface, wine_dbgstr_rect(dst_rect), src_surface, wine_dbgstr_rect(src_rect), flags, fx);
1811 
1812  return ddraw_surface7_Blt(&dst->IDirectDrawSurface7_iface, dst_rect,
1813  src_impl ? &src_impl->IDirectDrawSurface7_iface : NULL, src_rect, flags, fx);
1814 }
1815 
1816 static HRESULT WINAPI DECLSPEC_HOTPATCH ddraw_surface2_Blt(IDirectDrawSurface2 *iface, RECT *dst_rect,
1817  IDirectDrawSurface2 *src_surface, RECT *src_rect, DWORD flags, DDBLTFX *fx)
1818 {
1820  struct ddraw_surface *src_impl = unsafe_impl_from_IDirectDrawSurface2(src_surface);
1821 
1822  TRACE("iface %p, dst_rect %s, src_surface %p, src_rect %s, flags %#x, fx %p.\n",
1823  iface, wine_dbgstr_rect(dst_rect), src_surface, wine_dbgstr_rect(src_rect), flags, fx);
1824 
1825  return ddraw_surface7_Blt(&dst->IDirectDrawSurface7_iface, dst_rect,
1826  src_impl ? &src_impl->IDirectDrawSurface7_iface : NULL, src_rect, flags, fx);
1827 }
1828 
1829 static HRESULT WINAPI DECLSPEC_HOTPATCH ddraw_surface1_Blt(IDirectDrawSurface *iface, RECT *dst_rect,
1830  IDirectDrawSurface *src_surface, RECT *src_rect, DWORD flags, DDBLTFX *fx)
1831 {
1833  struct ddraw_surface *src_impl = unsafe_impl_from_IDirectDrawSurface(src_surface);
1834 
1835  TRACE("iface %p, dst_rect %s, src_surface %p, src_rect %s, flags %#x, fx %p.\n",
1836  iface, wine_dbgstr_rect(dst_rect), src_surface, wine_dbgstr_rect(src_rect), flags, fx);
1837 
1838  return ddraw_surface7_Blt(&dst->IDirectDrawSurface7_iface, dst_rect,
1839  src_impl ? &src_impl->IDirectDrawSurface7_iface : NULL, src_rect, flags, fx);
1840 }
1841 
1842 /*****************************************************************************
1843  * IDirectDrawSurface7::AddAttachedSurface
1844  *
1845  * Attaches a surface to another surface. How the surface attachments work
1846  * is not totally understood yet, and this method is prone to problems.
1847  * The surface that is attached is AddRef-ed.
1848  *
1849  * Tests with complex surfaces suggest that the surface attachments form a
1850  * tree, but no method to test this has been found yet.
1851  *
1852  * The attachment list consists of a first surface (first_attached) and
1853  * for each surface a pointer to the next attached surface (next_attached).
1854  * For the first surface, and a surface that has no attachments
1855  * first_attached points to the surface itself. A surface that has
1856  * no successors in the chain has next_attached set to NULL.
1857  *
1858  * Newly attached surfaces are attached right after the root surface.
1859  * If a surface is attached to a complex surface compound, it's attached to
1860  * the surface that the app requested, not the complex root. See
1861  * GetAttachedSurface for a description how surfaces are found.
1862  *
1863  * This is how the current implementation works, and it was coded by looking
1864  * at the needs of the applications.
1865  *
1866  * So far only Z-Buffer attachments are tested, and they are activated in
1867  * WineD3D. Mipmaps could be tricky to activate in WineD3D.
1868  * Back buffers should work in 2D mode, but they are not tested(They can be
1869  * attached in older iface versions). Rendering to the front buffer and
1870  * switching between that and double buffering is not yet implemented in
1871  * WineD3D, so for 3D it might have unexpected results.
1872  *
1873  * ddraw_surface_attach_surface is the real thing,
1874  * ddraw_surface7_AddAttachedSurface is a wrapper around it that
1875  * performs additional checks. Version 7 of this interface is much more restrictive
1876  * than its predecessors.
1877  *
1878  * Params:
1879  * Attach: Surface to attach to iface
1880  *
1881  * Returns:
1882  * DD_OK on success
1883  * DDERR_CANNOTATTACHSURFACE if the surface can't be attached for some reason
1884  *
1885  *****************************************************************************/
1887 {
1888  TRACE("surface %p, attachment %p.\n", This, Surf);
1889 
1890  if(Surf == This)
1891  return DDERR_CANNOTATTACHSURFACE; /* unchecked */
1892 
1894 
1895  /* Check if the surface is already attached somewhere */
1896  if (Surf->next_attached || Surf->first_attached != Surf)
1897  {
1898  /* TODO: Test for the structure of the manual attachment. Is it a
1899  * chain or a list? What happens if one surface is attached to 2
1900  * different surfaces? */
1901  WARN("Surface %p is already attached somewhere. next_attached %p, first_attached %p.\n",
1902  Surf, Surf->next_attached, Surf->first_attached);
1903 
1906  }
1907 
1908  /* This inserts the new surface at the 2nd position in the chain, right after the root surface */
1909  Surf->next_attached = This->next_attached;
1910  Surf->first_attached = This->first_attached;
1911  This->next_attached = Surf;
1912 
1913  /* Check if the WineD3D depth stencil needs updating */
1914  if (This->ddraw->d3ddevice)
1915  d3d_device_update_depth_stencil(This->ddraw->d3ddevice);
1916 
1918 
1919  return DD_OK;
1920 }
1921 
1923 {
1926  HRESULT hr;
1927 
1928  TRACE("iface %p, attachment %p.\n", iface, attachment);
1929 
1930  /* Version 7 of this interface seems to refuse everything except z buffers, as per msdn */
1931  if(!(attachment_impl->surface_desc.ddsCaps.dwCaps & DDSCAPS_ZBUFFER))
1932  {
1933 
1934  WARN("Application tries to attach a non Z buffer surface. caps %08x\n",
1935  attachment_impl->surface_desc.ddsCaps.dwCaps);
1937  }
1938 
1939  hr = ddraw_surface_attach_surface(This, attachment_impl);
1940  if (FAILED(hr))
1941  {
1942  return hr;
1943  }
1944  attachment_impl->attached_iface = (IUnknown *)attachment;
1945  IUnknown_AddRef(attachment_impl->attached_iface);
1946  return hr;
1947 }
1948 
1949 static HRESULT WINAPI ddraw_surface4_AddAttachedSurface(IDirectDrawSurface4 *iface, IDirectDrawSurface4 *attachment)
1950 {
1951  struct ddraw_surface *surface = impl_from_IDirectDrawSurface4(iface);
1953  HRESULT hr;
1954 
1955  TRACE("iface %p, attachment %p.\n", iface, attachment);
1956 
1957  /* Tests suggest that
1958  * -> offscreen plain surfaces can be attached to other offscreen plain surfaces
1959  * -> offscreen plain surfaces can be attached to primaries
1960  * -> primaries can be attached to offscreen plain surfaces
1961  * -> z buffers can be attached to primaries */
1964  {
1965  /* Sizes have to match */
1966  if (attachment_impl->surface_desc.dwWidth != surface->surface_desc.dwWidth
1967  || attachment_impl->surface_desc.dwHeight != surface->surface_desc.dwHeight)
1968  {
1969  WARN("Surface sizes do not match.\n");
1971  }
1972  }
1974  || !(attachment_impl->surface_desc.ddsCaps.dwCaps & (DDSCAPS_ZBUFFER)))
1975  {
1976  WARN("Invalid attachment combination.\n");
1978  }
1979 
1980  if (FAILED(hr = ddraw_surface_attach_surface(surface, attachment_impl)))
1981  return hr;
1982 
1983  attachment_impl->attached_iface = (IUnknown *)attachment;
1984  IUnknown_AddRef(attachment_impl->attached_iface);
1985  return hr;
1986 }
1987 
1988 static HRESULT WINAPI ddraw_surface3_AddAttachedSurface(IDirectDrawSurface3 *iface, IDirectDrawSurface3 *attachment)
1989 {
1990  struct ddraw_surface *surface = impl_from_IDirectDrawSurface3(iface);
1992  HRESULT hr;
1993 
1994  TRACE("iface %p, attachment %p.\n", iface, attachment);
1995 
1997  attachment_impl ? &attachment_impl->IDirectDrawSurface4_iface : NULL)))
1998  return hr;
1999 
2000  attachment_impl->attached_iface = (IUnknown *)attachment;
2001  IUnknown_AddRef(attachment_impl->attached_iface);
2003  return hr;
2004 }
2005 
2006 static HRESULT WINAPI ddraw_surface2_AddAttachedSurface(IDirectDrawSurface2 *iface, IDirectDrawSurface2 *attachment)
2007 {
2008  struct ddraw_surface *surface = impl_from_IDirectDrawSurface2(iface);
2010  HRESULT hr;
2011 
2012  TRACE("iface %p, attachment %p.\n", iface, attachment);
2013 
2015  attachment_impl ? &attachment_impl->IDirectDrawSurface4_iface : NULL)))
2016  return hr;
2017 
2018  attachment_impl->attached_iface = (IUnknown *)attachment;
2019  IUnknown_AddRef(attachment_impl->attached_iface);
2021  return hr;
2022 }
2023 
2024 static HRESULT WINAPI ddraw_surface1_AddAttachedSurface(IDirectDrawSurface *iface, IDirectDrawSurface *attachment)
2025 {
2026  struct ddraw_surface *surface = impl_from_IDirectDrawSurface(iface);
2028  HRESULT hr;
2029 
2030  TRACE("iface %p, attachment %p.\n", iface, attachment);
2031 
2033  attachment_impl ? &attachment_impl->IDirectDrawSurface4_iface : NULL)))
2034  return hr;
2035 
2036  attachment_impl->attached_iface = (IUnknown *)attachment;
2037  IUnknown_AddRef(attachment_impl->attached_iface);
2039  return hr;
2040 }
2041 
2042 /*****************************************************************************
2043  * IDirectDrawSurface7::DeleteAttachedSurface
2044  *
2045  * Removes a surface from the attachment chain. The surface's refcount
2046  * is decreased by one after it has been removed
2047  *
2048  * Params:
2049  * Flags: Some flags, not used by this implementation
2050  * Attach: Surface to detach
2051  *
2052  * Returns:
2053  * DD_OK on success
2054  * DDERR_SURFACENOTATTACHED if the surface isn't attached to
2055  *
2056  *****************************************************************************/
2058  struct ddraw_surface *attachment, IUnknown *detach_iface)
2059 {
2060  struct ddraw_surface *prev = surface;
2061 
2062  TRACE("surface %p, attachment %p, detach_iface %p.\n", surface, attachment, detach_iface);
2063 
2065  if (!attachment || (attachment->first_attached != surface) || (attachment == surface) )
2066  {
2069  }
2070 
2071  if (attachment->attached_iface != detach_iface)
2072  {
2073  WARN("attachment->attach_iface %p != detach_iface %p.\n", attachment->attached_iface, detach_iface);
2075  return DDERR_SURFACENOTATTACHED;
2076  }
2077 
2078  /* Remove MIPMAPSUBLEVEL if this seemed to be one */
2079  if (surface->surface_desc.ddsCaps.dwCaps & attachment->surface_desc.ddsCaps.dwCaps & DDSCAPS_MIPMAP)
2080  {
2081  attachment->surface_desc.ddsCaps.dwCaps2 &= ~DDSCAPS2_MIPMAPSUBLEVEL;
2082  /* FIXME: we should probably also subtract from dwMipMapCount of this
2083  * and all parent surfaces */
2084  }
2085 
2086  /* Find the predecessor of the detached surface */
2087  while (prev->next_attached != attachment)
2088  {
2089  if (!(prev = prev->next_attached))
2090  {
2091  ERR("Failed to find predecessor of %p.\n", attachment);
2093  return DDERR_SURFACENOTATTACHED;
2094  }
2095  }
2096 
2097  /* Unchain the surface */
2098  prev->next_attached = attachment->next_attached;
2099  attachment->next_attached = NULL;
2100  attachment->first_attached = attachment;
2101 
2102  /* Check if the wined3d depth stencil needs updating. Note that we don't
2103  * just call d3d_device_update_depth_stencil() here since it uses
2104  * QueryInterface(). Some applications, SCP - Containment Breach in
2105  * particular, modify the QueryInterface() pointer in the surface vtbl
2106  * but don't cleanup properly after the relevant dll is unloaded. */
2107  if (attachment->surface_desc.ddsCaps.dwCaps & DDSCAPS_ZBUFFER
2108  && wined3d_device_get_depth_stencil_view(surface->ddraw->wined3d_device) == attachment->wined3d_rtv)
2109  wined3d_device_set_depth_stencil_view(surface->ddraw->wined3d_device, NULL);
2111 
2112  /* Set attached_iface to NULL before releasing it, the surface may go
2113  * away. */
2114  attachment->attached_iface = NULL;
2115  IUnknown_Release(detach_iface);
2116 
2117  return DD_OK;
2118 }
2119 
2122 {
2123  struct ddraw_surface *surface = impl_from_IDirectDrawSurface7(iface);
2125 
2126  TRACE("iface %p, flags %#x, attachment %p.\n", iface, flags, attachment);
2127 
2128  return ddraw_surface_delete_attached_surface(surface, attachment_impl, (IUnknown *)attachment);
2129 }
2130 
2131 static HRESULT WINAPI ddraw_surface4_DeleteAttachedSurface(IDirectDrawSurface4 *iface,
2132  DWORD flags, IDirectDrawSurface4 *attachment)
2133 {
2134  struct ddraw_surface *surface = impl_from_IDirectDrawSurface4(iface);
2136 
2137  TRACE("iface %p, flags %#x, attachment %p.\n", iface, flags, attachment);
2138 
2139  return ddraw_surface_delete_attached_surface(surface, attachment_impl, (IUnknown *)attachment);
2140 }
2141 
2142 static HRESULT WINAPI ddraw_surface3_DeleteAttachedSurface(IDirectDrawSurface3 *iface,
2143  DWORD flags, IDirectDrawSurface3 *attachment)
2144 {
2145  struct ddraw_surface *surface = impl_from_IDirectDrawSurface3(iface);
2147 
2148  TRACE("iface %p, flags %#x, attachment %p.\n", iface, flags, attachment);
2149 
2150  return ddraw_surface_delete_attached_surface(surface, attachment_impl, (IUnknown *)attachment);
2151 }
2152 
2153 static HRESULT WINAPI ddraw_surface2_DeleteAttachedSurface(IDirectDrawSurface2 *iface,
2154  DWORD flags, IDirectDrawSurface2 *attachment)
2155 {
2156  struct ddraw_surface *surface = impl_from_IDirectDrawSurface2(iface);
2158 
2159  TRACE("iface %p, flags %#x, attachment %p.\n", iface, flags, attachment);
2160 
2161  return ddraw_surface_delete_attached_surface(surface, attachment_impl, (IUnknown *)attachment);
2162 }
2163 
2164 static HRESULT WINAPI ddraw_surface1_DeleteAttachedSurface(IDirectDrawSurface *iface,
2165  DWORD flags, IDirectDrawSurface *attachment)
2166 {
2167  struct ddraw_surface *surface = impl_from_IDirectDrawSurface(iface);
2169 
2170  TRACE("iface %p, flags %#x, attachment %p.\n", iface, flags, attachment);
2171 
2172  return ddraw_surface_delete_attached_surface(surface, attachment_impl, (IUnknown *)attachment);
2173 }
2174 
2175 /*****************************************************************************
2176  * IDirectDrawSurface7::AddOverlayDirtyRect
2177  *
2178  * "This method is not currently implemented"
2179  *
2180  * Params:
2181  * Rect: ?
2182  *
2183  * Returns:
2184  * DDERR_UNSUPPORTED
2185  *
2186  *****************************************************************************/
2188 {
2189  TRACE("iface %p, rect %s.\n", iface, wine_dbgstr_rect(Rect));
2190 
2191  return DDERR_UNSUPPORTED; /* unchecked */
2192 }
2193 
2194 static HRESULT WINAPI ddraw_surface4_AddOverlayDirtyRect(IDirectDrawSurface4 *iface, RECT *rect)
2195 {
2196  struct ddraw_surface *surface = impl_from_IDirectDrawSurface4(iface);
2197 
2198  TRACE("iface %p, rect %s.\n", iface, wine_dbgstr_rect(rect));
2199 
2201 }
2202 
2203 static HRESULT WINAPI ddraw_surface3_AddOverlayDirtyRect(IDirectDrawSurface3 *iface, RECT *rect)
2204 {
2205  struct ddraw_surface *surface = impl_from_IDirectDrawSurface3(iface);
2206 
2207  TRACE("iface %p, rect %s.\n", iface, wine_dbgstr_rect(rect));
2208 
2210 }
2211 
2212 static HRESULT WINAPI ddraw_surface2_AddOverlayDirtyRect(IDirectDrawSurface2 *iface, RECT *rect)
2213 {
2214  struct ddraw_surface *surface = impl_from_IDirectDrawSurface2(iface);
2215 
2216  TRACE("iface %p, rect %s.\n", iface, wine_dbgstr_rect(rect));
2217 
2219 }
2220 
2221 static HRESULT WINAPI ddraw_surface1_AddOverlayDirtyRect(IDirectDrawSurface *iface, RECT *rect)
2222 {
2223  struct ddraw_surface *surface = impl_from_IDirectDrawSurface(iface);
2224 
2225  TRACE("iface %p, rect %s.\n", iface, wine_dbgstr_rect(rect));
2226 
2228 }
2229 
2230 /*****************************************************************************
2231  * IDirectDrawSurface7::GetDC
2232  *
2233  * Returns a GDI device context for the surface
2234  *
2235  * Params:
2236  * hdc: Address of a HDC variable to store the dc to
2237  *
2238  * Returns:
2239  * DD_OK on success
2240  * DDERR_INVALIDPARAMS if hdc is NULL
2241  *
2242  *****************************************************************************/
2244 {
2245  struct ddraw_surface *surface = impl_from_IDirectDrawSurface7(iface);
2246  HRESULT hr = DD_OK;
2247 
2248  TRACE("iface %p, dc %p.\n", iface, dc);
2249 
2250  if (!dc)
2251  return DDERR_INVALIDPARAMS;
2252 
2254  if (surface->dc)
2256  else if (surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)
2257  hr = ddraw_surface_update_frontbuffer(surface, NULL, TRUE, 0);
2258  if (SUCCEEDED(hr))
2260 
2261  if (SUCCEEDED(hr))
2262  {
2263  surface->dc = *dc;
2264 
2266  {
2267  const struct ddraw_palette *palette;
2268 
2269  if (surface->palette)
2270  palette = surface->palette;
2271  else if (surface->ddraw->primary)
2272  palette = surface->ddraw->primary->palette;
2273  else
2274  palette = NULL;
2275 
2276  if (palette)
2277  wined3d_palette_apply_to_dc(palette->wined3d_palette, *dc);
2278  }
2279  }
2280 
2282  switch (hr)
2283  {
2284  /* Some, but not all errors set *dc to NULL. E.g. DCALREADYCREATED
2285  * does not touch *dc. */
2287  *dc = NULL;
2288  return DDERR_CANTCREATEDC;
2289 
2290  default:
2291  return hr;
2292  }
2293 }
2294 
2295 static HRESULT WINAPI ddraw_surface4_GetDC(IDirectDrawSurface4 *iface, HDC *dc)
2296 {
2297  struct ddraw_surface *surface = impl_from_IDirectDrawSurface4(iface);
2298 
2299  TRACE("iface %p, dc %p.\n", iface, dc);
2300 
2302 }
2303 
2304 static HRESULT WINAPI ddraw_surface3_GetDC(IDirectDrawSurface3 *iface, HDC *dc)
2305 {
2306  struct ddraw_surface *surface = impl_from_IDirectDrawSurface3(iface);
2307 
2308  TRACE("iface %p, dc %p.\n", iface, dc);
2309 
2311 }
2312 
2313 static HRESULT WINAPI ddraw_surface2_GetDC(IDirectDrawSurface2 *iface, HDC *dc)
2314 {
2315  struct ddraw_surface *surface = impl_from_IDirectDrawSurface2(iface);
2316 
2317  TRACE("iface %p, dc %p.\n", iface, dc);
2318 
2320 }
2321 
2322 static HRESULT WINAPI ddraw_surface1_GetDC(IDirectDrawSurface *iface, HDC *dc)
2323 {
2324  struct ddraw_surface *surface = impl_from_IDirectDrawSurface(iface);
2325 
2326  TRACE("iface %p, dc %p.\n", iface, dc);
2327 
2329 }
2330 
2331 /*****************************************************************************
2332  * IDirectDrawSurface7::ReleaseDC
2333  *
2334  * Releases the DC that was constructed with GetDC
2335  *
2336  * Params:
2337  * hdc: HDC to release
2338  *
2339  * Returns:
2340  * DD_OK on success, error code otherwise.
2341  *
2342  *****************************************************************************/
2344 {
2345  struct ddraw_surface *surface = impl_from_IDirectDrawSurface7(iface);
2346  HRESULT hr;
2347 
2348  TRACE("iface %p, dc %p.\n", iface, hdc);
2349 #ifdef __REACTOS__
2350  GdiFlush();
2351 #endif
2353  if (!surface->dc)
2354  {
2355  hr = DDERR_NODC;
2356  }
2358  {
2359  surface->dc = NULL;
2362  }
2364 
2365 
2366  return hr;
2367 }
2368 
2369 static HRESULT WINAPI ddraw_surface4_ReleaseDC(IDirectDrawSurface4 *iface, HDC dc)
2370 {
2371  struct ddraw_surface *surface = impl_from_IDirectDrawSurface4(iface);
2372 
2373  TRACE("iface %p, dc %p.\n", iface, dc);
2374 
2376 }
2377 
2378 static HRESULT WINAPI ddraw_surface3_ReleaseDC(IDirectDrawSurface3 *iface, HDC dc)
2379 {
2380  struct ddraw_surface *surface = impl_from_IDirectDrawSurface3(iface);
2381 
2382  TRACE("iface %p, dc %p.\n", iface, dc);
2383 
2385 }
2386 
2387 static HRESULT WINAPI ddraw_surface2_ReleaseDC(IDirectDrawSurface2 *iface, HDC dc)
2388 {
2389  struct ddraw_surface *surface = impl_from_IDirectDrawSurface2(iface);
2390 
2391  TRACE("iface %p, dc %p.\n", iface, dc);
2392 
2394 }
2395 
2396 static HRESULT WINAPI ddraw_surface1_ReleaseDC(IDirectDrawSurface *iface, HDC dc)
2397 {
2398  struct ddraw_surface *surface = impl_from_IDirectDrawSurface(iface);
2399 
2400  TRACE("iface %p, dc %p.\n", iface, dc);
2401 
2403 }
2404 
2405 /*****************************************************************************
2406  * IDirectDrawSurface7::GetCaps
2407  *
2408  * Returns the surface's caps
2409  *
2410  * Params:
2411  * Caps: Address to write the caps to
2412  *
2413  * Returns:
2414  * DD_OK on success
2415  * DDERR_INVALIDPARAMS if Caps is NULL
2416  *
2417  *****************************************************************************/
2419 {
2420  struct ddraw_surface *surface = impl_from_IDirectDrawSurface7(iface);
2421 
2422  TRACE("iface %p, caps %p.\n", iface, Caps);
2423 
2424  if(!Caps)
2425  return DDERR_INVALIDPARAMS;
2426 
2427  *Caps = surface->surface_desc.ddsCaps;
2428 
2429  return DD_OK;
2430 }
2431 
2432 static HRESULT WINAPI ddraw_surface4_GetCaps(IDirectDrawSurface4 *iface, DDSCAPS2 *caps)
2433 {
2434  struct ddraw_surface *surface = impl_from_IDirectDrawSurface4(iface);
2435 
2436  TRACE("iface %p, caps %p.\n", iface, caps);
2437 
2438  return ddraw_surface7_GetCaps(&surface->IDirectDrawSurface7_iface, caps);
2439 }
2440 
2441 static HRESULT WINAPI ddraw_surface3_GetCaps(IDirectDrawSurface3 *iface, DDSCAPS *caps)
2442 {
2443  struct ddraw_surface *surface = impl_from_IDirectDrawSurface3(iface);
2444  DDSCAPS2 caps2;
2445  HRESULT hr;
2446 
2447  TRACE("iface %p, caps %p.\n", iface, caps);
2448 
2450  if (FAILED(hr)) return hr;
2451 
2452  caps->dwCaps = caps2.dwCaps;
2453  return hr;
2454 }
2455 
2456 static HRESULT WINAPI ddraw_surface2_GetCaps(IDirectDrawSurface2 *iface, DDSCAPS *caps)
2457 {
2458  struct ddraw_surface *surface = impl_from_IDirectDrawSurface2(iface);
2459  DDSCAPS2 caps2;
2460  HRESULT hr;
2461 
2462  TRACE("iface %p, caps %p.\n", iface, caps);
2463 
2465  if (FAILED(hr)) return hr;
2466 
2467  caps->dwCaps = caps2.dwCaps;
2468  return hr;
2469 }
2470 
2471 static HRESULT WINAPI ddraw_surface1_GetCaps(IDirectDrawSurface *iface, DDSCAPS *caps)
2472 {
2473  struct ddraw_surface *surface = impl_from_IDirectDrawSurface(iface);
2474  DDSCAPS2 caps2;
2475  HRESULT hr;
2476 
2477  TRACE("iface %p, caps %p.\n", iface, caps);
2478 
2480  if (FAILED(hr)) return hr;
2481 
2482  caps->dwCaps = caps2.dwCaps;
2483  return hr;
2484 }
2485 
2487 {
2488  struct ddraw_surface *surface = impl_from_IDirectDrawSurface7(iface);
2490  HRESULT hr;
2491  struct wined3d_resource *resource;
2492 
2493  TRACE("iface %p, priority %u.\n", iface, priority);
2494 
2496  /* No need to check for offscreen plain surfaces or mipmap sublevels. SetPriority
2497  * calls on such surfaces segfault on Windows. */
2498  if (!(surface->surface_desc.ddsCaps.dwCaps2 & managed))
2499  {
2500  WARN("Called on non-managed texture returning DDERR_INVALIDPARAMS.\n");
2502  }
2503  else
2504  {
2507  hr = DD_OK;
2508  }
2510 
2511  return hr;
2512 }
2513 
2515 {
2516  struct ddraw_surface *surface = impl_from_IDirectDrawSurface7(iface);
2517  const struct wined3d_resource *resource;
2519  HRESULT hr;
2520 
2521  TRACE("iface %p, priority %p.\n", iface, priority);
2522 
2525  {
2526  WARN("Called on offscreenplain surface, returning DDERR_INVALIDOBJECT.\n");
2528  }
2529  else if (!(surface->surface_desc.ddsCaps.dwCaps2 & managed) || !surface->is_complex_root)
2530  {
2531  WARN("Called on non-managed texture or non-root surface, returning DDERR_INVALIDPARAMS.\n");
2533  }
2534  else
2535  {
2538  hr = DD_OK;
2539  }
2541 
2542  return hr;
2543 }
2544 
2545 /*****************************************************************************
2546  * IDirectDrawSurface7::SetPrivateData
2547  *
2548  * Stores some data in the surface that is intended for the application's
2549  * use.
2550  *
2551  * Params:
2552  * tag: GUID that identifies the data
2553  * Data: Pointer to the private data
2554  * Size: Size of the private data
2555  * Flags: Some flags
2556  *
2557  * Returns:
2558  * D3D_OK on success, error code otherwise.
2559  *
2560  *****************************************************************************/
2562  REFGUID tag, void *data, DWORD size, DWORD flags)
2563 {
2564  struct ddraw_surface *surface = impl_from_IDirectDrawSurface7(iface);
2565  HRESULT hr;
2566 
2567  TRACE("iface %p, tag %s, data %p, data_size %u, flags %#x.\n",
2568  iface, debugstr_guid(tag), data, size, flags);
2569 
2570  if (!data)
2571  {
2572  WARN("data is NULL, returning DDERR_INVALIDPARAMS.\n");
2573  return DDERR_INVALIDPARAMS;
2574  }
2575 
2579  return hr_ddraw_from_wined3d(hr);
2580 }
2581 
2582 static HRESULT WINAPI ddraw_surface4_SetPrivateData(IDirectDrawSurface4 *iface,
2583  REFGUID tag, void *data, DWORD size, DWORD flags)
2584 {
2585  struct ddraw_surface *surface = impl_from_IDirectDrawSurface4(iface);
2586 
2587  TRACE("iface %p, tag %s, data %p, data_size %u, flags %#x.\n",
2588  iface, debugstr_guid(tag), data, size, flags);
2589 
2591 }
2592 
2593 /*****************************************************************************
2594  * IDirectDrawSurface7::GetPrivateData
2595  *
2596  * Returns the private data set with IDirectDrawSurface7::SetPrivateData
2597  *
2598  * Params:
2599  * tag: GUID of the data to return
2600  * Data: Address where to write the data to
2601  * Size: Size of the buffer at Data
2602  *
2603  * Returns:
2604  * DD_OK on success
2605  * DDERR_INVALIDPARAMS if Data is NULL
2606  *
2607  *****************************************************************************/
2609 {
2610  struct ddraw_surface *surface = impl_from_IDirectDrawSurface7(iface);
2611  const struct wined3d_private_data *stored_data;
2612  HRESULT hr;
2613 
2614  TRACE("iface %p, tag %s, data %p, data_size %p.\n",
2615  iface, debugstr_guid(tag), data, size);
2616 
2618  stored_data = wined3d_private_store_get_private_data(&surface->private_store, tag);
2619  if (!stored_data)
2620  {
2621  hr = DDERR_NOTFOUND;
2622  goto done;
2623  }
2624  if (!size)
2625  {
2627  goto done;
2628  }
2630  {
2631  *size = stored_data->size;
2632  hr = DDERR_MOREDATA;
2633  goto done;
2634  }
2635  if (!data)
2636  {
2638  goto done;
2639  }
2640 
2641  *size = stored_data->size;
2642  memcpy(data, stored_data->content.data, stored_data->size);
2643  hr = DD_OK;
2644 
2645 done:
2647  return hr;
2648 }
2649 
2650 static HRESULT WINAPI ddraw_surface4_GetPrivateData(IDirectDrawSurface4 *iface, REFGUID tag, void *data, DWORD *size)
2651 {
2652  struct ddraw_surface *surface = impl_from_IDirectDrawSurface4(iface);
2653 
2654  TRACE("iface %p, tag %s, data %p, data_size %p.\n",
2655  iface, debugstr_guid(tag), data, size);
2656 
2658 }
2659 
2660 /*****************************************************************************
2661  * IDirectDrawSurface7::FreePrivateData
2662  *
2663  * Frees private data stored in the surface
2664  *
2665  * Params:
2666  * tag: Tag of the data to free
2667  *
2668  * Returns:
2669  * D3D_OK on success, error code otherwise.
2670  *
2671  *****************************************************************************/
2673 {
2674  struct ddraw_surface *surface = impl_from_IDirectDrawSurface7(iface);
2675  struct wined3d_private_data *entry;
2676 
2677  TRACE("iface %p, tag %s.\n", iface, debugstr_guid(tag));
2678 
2681  if (!entry)
2682  {
2684  return DDERR_NOTFOUND;
2685  }
2686 
2689 
2690  return DD_OK;
2691 }
2692 
2693 static HRESULT WINAPI ddraw_surface4_FreePrivateData(IDirectDrawSurface4 *iface, REFGUID tag)
2694 {
2695  struct ddraw_surface *surface = impl_from_IDirectDrawSurface4(iface);
2696 
2697  TRACE("iface %p, tag %s.\n", iface, debugstr_guid(tag));
2698 
2700 }
2701 
2702 /*****************************************************************************
2703  * IDirectDrawSurface7::PageLock
2704  *
2705  * Prevents a sysmem surface from being paged out
2706  *
2707  * Params:
2708  * Flags: Not used, must be 0(unchecked)
2709  *
2710  * Returns:
2711  * DD_OK, because it's a stub
2712  *
2713  *****************************************************************************/
2715 {
2716  TRACE("iface %p, flags %#x.\n", iface, Flags);
2717 
2718  /* This is Windows memory management related - we don't need this */
2719  return DD_OK;
2720 }
2721 
2722 static HRESULT WINAPI ddraw_surface4_PageLock(IDirectDrawSurface4 *iface, DWORD flags)
2723 {
2724  struct ddraw_surface *surface = impl_from_IDirectDrawSurface4(iface);
2725 
2726  TRACE("iface %p, flags %#x.\n", iface, flags);
2727 
2729 }
2730 
2731 static HRESULT WINAPI ddraw_surface3_PageLock(IDirectDrawSurface3 *iface, DWORD flags)
2732 {
2733  struct ddraw_surface *surface = impl_from_IDirectDrawSurface3(iface);
2734 
2735  TRACE("iface %p, flags %#x.\n", iface, flags);
2736 
2738 }
2739 
2740 static HRESULT WINAPI ddraw_surface2_PageLock(IDirectDrawSurface2 *iface, DWORD flags)
2741 {
2742  struct ddraw_surface *surface = impl_from_IDirectDrawSurface2(iface);
2743 
2744  TRACE("iface %p, flags %#x.\n", iface, flags);
2745 
2747 }
2748 
2749 /*****************************************************************************
2750  * IDirectDrawSurface7::PageUnlock
2751  *
2752  * Allows a sysmem surface to be paged out
2753  *
2754  * Params:
2755  * Flags: Not used, must be 0(unchecked)
2756  *
2757  * Returns:
2758  * DD_OK, because it's a stub
2759  *
2760  *****************************************************************************/
2762 {
2763  TRACE("iface %p, flags %#x.\n", iface, Flags);
2764 
2765  return DD_OK;
2766 }
2767 
2768 static HRESULT WINAPI ddraw_surface4_PageUnlock(IDirectDrawSurface4 *iface, DWORD flags)
2769 {
2770  struct ddraw_surface *surface = impl_from_IDirectDrawSurface4(iface);
2771 
2772  TRACE("iface %p, flags %#x.\n", iface, flags);
2773 
2775 }
2776 
2777 static HRESULT WINAPI ddraw_surface3_PageUnlock(IDirectDrawSurface3 *iface, DWORD flags)
2778 {
2779  struct ddraw_surface *surface = impl_from_IDirectDrawSurface3(iface);
2780 
2781  TRACE("iface %p, flags %#x.\n", iface, flags);
2782 
2784 }
2785 
2786 static HRESULT WINAPI ddraw_surface2_PageUnlock(IDirectDrawSurface2 *iface, DWORD flags)
2787 {
2788  struct ddraw_surface *surface = impl_from_IDirectDrawSurface2(iface);
2789 
2790  TRACE("iface %p, flags %#x.\n", iface, flags);
2791 
2793 }
2794 
2795 /*****************************************************************************
2796  * IDirectDrawSurface7::BltBatch
2797  *
2798  * An unimplemented function
2799  *
2800  * Params:
2801  * ?
2802  *
2803  * Returns:
2804  * DDERR_UNSUPPORTED
2805  *
2806  *****************************************************************************/
2808 {
2809  TRACE("iface %p, batch %p, count %u, flags %#x.\n", iface, Batch, Count, Flags);
2810 
2811  /* MSDN: "not currently implemented" */
2812  return DDERR_UNSUPPORTED;
2813 }
2814 
2816 {
2817  struct ddraw_surface *surface = impl_from_IDirectDrawSurface4(iface);
2818 
2819  TRACE("iface %p, batch %p, count %u, flags %#x.\n", iface, batch, count, flags);
2820 
2821  return ddraw_surface7_BltBatch(&surface->IDirectDrawSurface7_iface, batch, count, flags);
2822 }
2823 
2825 {
2826  struct ddraw_surface *surface = impl_from_IDirectDrawSurface3(iface);
2827 
2828  TRACE("iface %p, batch %p, count %u, flags %#x.\n", iface, batch, count, flags);
2829 
2830  return ddraw_surface7_BltBatch(&surface->IDirectDrawSurface7_iface, batch, count, flags);
2831 }
2832 
2834 {
2835  struct ddraw_surface *surface = impl_from_IDirectDrawSurface2(iface);
2836 
2837  TRACE("iface %p, batch %p, count %u, flags %#x.\n", iface, batch, count, flags);
2838 
2839  return ddraw_surface7_BltBatch(&surface->IDirectDrawSurface7_iface, batch, count, flags);
2840 }
2841 
2843 {
2844  struct ddraw_surface *surface = impl_from_IDirectDrawSurface(iface);
2845 
2846  TRACE("iface %p, batch %p, count %u, flags %#x.\n", iface, batch, count, flags);
2847 
2848  return ddraw_surface7_BltBatch(&surface->IDirectDrawSurface7_iface, batch, count, flags);
2849 }
2850 
2851 /*****************************************************************************
2852  * IDirectDrawSurface7::EnumAttachedSurfaces
2853  *
2854  * Enumerates all surfaces attached to this surface
2855  *
2856  * Params:
2857  * context: Pointer to pass unmodified to the callback
2858  * cb: Callback function to call for each surface
2859  *
2860  * Returns:
2861  * DD_OK on success
2862  * DDERR_INVALIDPARAMS if cb is NULL
2863  *
2864  *****************************************************************************/
2867 {
2868  struct ddraw_surface *surface = impl_from_IDirectDrawSurface7(iface);
2869  struct ddraw_surface *surf;
2871  int i;
2872 
2873  /* Attached surfaces aren't handled in WineD3D */
2874  TRACE("iface %p, context %p, callback %p.\n", iface, context, cb);
2875 
2876  if(!cb)
2877  return DDERR_INVALIDPARAMS;
2878 
2880 
2881  for(i = 0; i < MAX_COMPLEX_ATTACHED; i++)
2882  {
2883  surf = surface->complex_array[i];
2884  if(!surf) break;
2885 
2887  desc = surf->surface_desc;
2888  /* check: != DDENUMRET_OK or == DDENUMRET_CANCEL? */
2890  {
2892  return DD_OK;
2893  }
2894  }
2895 
2896  for (surf = surface->next_attached; surf != NULL; surf = surf->next_attached)
2897  {
2899  desc = surf->surface_desc;
2900  /* check: != DDENUMRET_OK or == DDENUMRET_CANCEL? */
2902  {
2904  return DD_OK;
2905  }
2906  }
2907 
2908  TRACE(" end of enumeration.\n");
2909 
2911 
2912  return DD_OK;
2913 }
2914 
2916 {
2918  void *context;
2919 };
2920 
2921 struct callback_info
2922 {
2924  void *context;
2925 };
2926 
2928 {
2929  struct ddraw_surface *surface_impl = impl_from_IDirectDrawSurface7(surface);
2930  const struct callback_info2 *info = context;
2931 
2933  ddraw_surface7_Release(surface);
2934 
2935  return info->callback(&surface_impl->IDirectDrawSurface4_iface, surface_desc, info->context);
2936 }
2937 
2939 {
2940  struct ddraw_surface *surface_impl = impl_from_IDirectDrawSurface7(surface);
2941  const struct callback_info *info = context;
2942 
2944  ddraw_surface7_Release(surface);
2945 
2946  /* FIXME: Check surface_test.dwSize */
2947  return info->callback(&surface_impl->IDirectDrawSurface_iface,
2948  (DDSURFACEDESC *)surface_desc, info->context);
2949 }
2950 
2951 static HRESULT WINAPI ddraw_surface4_EnumAttachedSurfaces(IDirectDrawSurface4 *iface,
2953 {
2954  struct ddraw_surface *surface = impl_from_IDirectDrawSurface4(iface);
2955  struct callback_info2 info;
2956 
2957  TRACE("iface %p, context %p, callback %p.\n", iface, context, callback);
2958 
2959  info.callback = callback;
2960  info.context = context;
2961 
2963  &info, EnumCallback2);
2964 }
2965 
2966 static HRESULT WINAPI ddraw_surface3_EnumAttachedSurfaces(IDirectDrawSurface3 *iface,
2968 {
2969  struct ddraw_surface *surface = impl_from_IDirectDrawSurface3(iface);
2970  struct callback_info info;
2971 
2972  TRACE("iface %p, context %p, callback %p.\n", iface, context, callback);
2973 
2974  info.callback = callback;
2975  info.context = context;
2976 
2978  &info, EnumCallback);
2979 }
2980 
2981 static HRESULT WINAPI ddraw_surface2_EnumAttachedSurfaces(IDirectDrawSurface2 *iface,
2983 {
2984  struct ddraw_surface *surface = impl_from_IDirectDrawSurface2(iface);
2985  struct callback_info info;
2986 
2987  TRACE("iface %p, context %p, callback %p.\n", iface, context, callback);
2988 
2989  info.callback = callback;
2990  info.context = context;
2991 
2993  &info, EnumCallback);
2994 }
2995 
2996 static HRESULT WINAPI ddraw_surface1_EnumAttachedSurfaces(IDirectDrawSurface *iface,
2998 {
2999  struct ddraw_surface *surface = impl_from_IDirectDrawSurface(iface);
3000  struct callback_info info;
3001 
3002  TRACE("iface %p, context %p, callback %p.\n", iface, context, callback);
3003 
3004  info.callback = callback;
3005  info.context = context;
3006 
3008  &info, EnumCallback);
3009 }
3010 
3011 /*****************************************************************************
3012  * IDirectDrawSurface7::EnumOverlayZOrders
3013  *
3014  * "Enumerates the overlay surfaces on the specified destination"
3015  *
3016  * Params:
3017  * Flags: DDENUMOVERLAYZ_BACKTOFRONT or DDENUMOVERLAYZ_FRONTTOBACK
3018  * context: context to pass back to the callback
3019  * cb: callback function to call for each enumerated surface
3020  *
3021  * Returns:
3022  * DD_OK, because it's a stub
3023  *
3024  *****************************************************************************/
3027 {
3028  FIXME("iface %p, flags %#x, context %p, callback %p stub!\n", iface, Flags, context, cb);
3029 
3030  return DD_OK;
3031 }
3032 
3033 static HRESULT WINAPI ddraw_surface4_EnumOverlayZOrders(IDirectDrawSurface4 *iface,
3035 {
3036  struct ddraw_surface *surface = impl_from_IDirectDrawSurface4(iface);
3037  struct callback_info2 info;
3038 
3039  TRACE("iface %p, flags %#x, context %p, callback %p.\n", iface, flags, context, callback);
3040 
3041  info.callback = callback;
3042  info.context = context;
3043 
3045  flags, &info, EnumCallback2);
3046 }
3047 
3048 static HRESULT WINAPI ddraw_surface3_EnumOverlayZOrders(IDirectDrawSurface3 *iface,
3050 {
3051  struct ddraw_surface *surface = impl_from_IDirectDrawSurface3(iface);
3052  struct callback_info info;
3053 
3054  TRACE("iface %p, flags %#x, context %p, callback %p.\n", iface, flags, context, callback);
3055 
3056  info.callback = callback;
3057  info.context = context;
3058 
3060  flags, &info, EnumCallback);
3061 }
3062 
3063 static HRESULT WINAPI ddraw_surface2_EnumOverlayZOrders(IDirectDrawSurface2 *iface,
3065 {
3066  struct ddraw_surface *surface = impl_from_IDirectDrawSurface2(iface);
3067  struct callback_info info;
3068 
3069  TRACE("iface %p, flags %#x, context %p, callback %p.\n", iface, flags, context, callback);
3070 
3071  info.callback = callback;
3072  info.context = context;
3073 
3075  flags, &info, EnumCallback);
3076 }
3077 
3078 static HRESULT WINAPI ddraw_surface1_EnumOverlayZOrders(IDirectDrawSurface *iface,
3080 {
3081  struct ddraw_surface *surface = impl_from_IDirectDrawSurface(iface);
3082  struct callback_info info;
3083 
3084  TRACE("iface %p, flags %#x, context %p, callback %p.\n", iface, flags, context, callback);
3085 
3086  info.callback = callback;
3087  info.context = context;
3088 
3090  flags, &info, EnumCallback);
3091 }
3092 
3093 /*****************************************************************************
3094  * IDirectDrawSurface7::GetBltStatus
3095  *
3096  * Returns the blitting status
3097  *
3098  * Params:
3099  * Flags: DDGBS_CANBLT or DDGBS_ISBLTDONE
3100  *
3101  *****************************************************************************/
3103 {
3104  TRACE("iface %p, flags %#x.\n", iface, Flags);
3105 
3106  switch (Flags)
3107  {
3108  case WINEDDGBS_CANBLT:
3109  case WINEDDGBS_ISBLTDONE:
3110  return DD_OK;
3111 
3112  default:
3113  return DDERR_INVALIDPARAMS;
3114  }
3115 }
3116 
3117 static HRESULT WINAPI ddraw_surface4_GetBltStatus(IDirectDrawSurface4 *iface, DWORD flags)
3118 {
3119  struct ddraw_surface *surface = impl_from_IDirectDrawSurface4(iface);
3120 
3121  TRACE("iface %p, flags %#x.\n", iface, flags);
3122 
3124 }
3125 
3126 static HRESULT WINAPI ddraw_surface3_GetBltStatus(IDirectDrawSurface3 *iface, DWORD flags)
3127 {
3128  struct ddraw_surface *surface = impl_from_IDirectDrawSurface3(iface);
3129 
3130  TRACE("iface %p, flags %#x.\n", iface, flags);
3131 
3133 }
3134 
3135 static HRESULT WINAPI ddraw_surface2_GetBltStatus(IDirectDrawSurface2 *iface, DWORD flags)
3136 {
3137  struct ddraw_surface *surface = impl_from_IDirectDrawSurface2(iface);
3138 
3139  TRACE("iface %p, flags %#x.\n", iface, flags);
3140 
3142 }
3143 
3144 static HRESULT WINAPI ddraw_surface1_GetBltStatus(IDirectDrawSurface *iface, DWORD flags)
3145 {
3146  struct ddraw_surface *surface = impl_from_IDirectDrawSurface(iface);
3147 
3148  TRACE("iface %p, flags %#x.\n", iface, flags);
3149 
3151 }
3152 
3153 /*****************************************************************************
3154  * IDirectDrawSurface7::GetColorKey
3155  *
3156  * Returns the color key assigned to the surface
3157  *
3158  * Params:
3159  * Flags: Some flags
3160  * CKey: Address to store the key to
3161  *
3162  * Returns:
3163  * DD_OK on success
3164  * DDERR_INVALIDPARAMS if CKey is NULL
3165  *
3166  *****************************************************************************/
3168 {
3170 
3171  TRACE("iface %p, flags %#x, color_key %p.\n", iface, Flags, CKey);
3172 
3173  if(!CKey)
3174  return DDERR_INVALIDPARAMS;
3175 
3177 
3178  switch (Flags)
3179  {
3180  case DDCKEY_DESTBLT:
3181  if (!(This->surface_desc.dwFlags & DDSD_CKDESTBLT))
3182  {
3184  return DDERR_NOCOLORKEY;
3185  }
3186  *CKey = This->surface_desc.ddckCKDestBlt;
3187  break;
3188 
3189  case DDCKEY_DESTOVERLAY:
3190  if (!(This->surface_desc.dwFlags & DDSD_CKDESTOVERLAY))
3191  {
3193  return DDERR_NOCOLORKEY;
3194  }
3195  *CKey = This->surface_desc.u3.ddckCKDestOverlay;
3196  break;
3197 
3198  case DDCKEY_SRCBLT:
3199  if (!(This->surface_desc.dwFlags & DDSD_CKSRCBLT))
3200  {
3202  return DDERR_NOCOLORKEY;
3203  }
3204  *CKey = This->surface_desc.ddckCKSrcBlt;
3205  break;
3206 
3207  case DDCKEY_SRCOVERLAY:
3208  if (!(This->surface_desc.dwFlags & DDSD_CKSRCOVERLAY))
3209  {
3211  return DDERR_NOCOLORKEY;
3212  }
3213  *CKey = This->surface_desc.ddckCKSrcOverlay;
3214  break;
3215 
3216  default:
3218  return DDERR_INVALIDPARAMS;
3219  }
3220 
3222 
3223  return DD_OK;
3224 }
3225 
3227 {
3228  struct ddraw_surface *surface = impl_from_IDirectDrawSurface4(iface);
3229 
3230  TRACE("iface %p, flags %#x, color_key %p.\n", iface, flags, color_key);
3231 
3233 }
3234 
3236 {
3237  struct ddraw_surface *surface = impl_from_IDirectDrawSurface3(iface);
3238 
3239  TRACE("iface %p, flags %#x, color_key %p.\n", iface, flags, color_key);
3240 
3242 }
3243 
3245 {
3246  struct ddraw_surface *surface = impl_from_IDirectDrawSurface2(iface);
3247 
3248  TRACE("iface %p, flags %#x, color_key %p.\n", iface, flags, color_key);
3249 
3251 }
3252 
3254 {
3255  struct ddraw_surface *surface = impl_from_IDirectDrawSurface(iface);
3256 
3257  TRACE("iface %p, flags %#x, color_key %p.\n", iface, flags, color_key);
3258 
3260 }
3261 
3262 /*****************************************************************************
3263  * IDirectDrawSurface7::GetFlipStatus
3264  *
3265  * Returns the flipping status of the surface
3266  *
3267  * Params:
3268  * Flags: DDGFS_CANFLIP of DDGFS_ISFLIPDONE
3269  *
3270  *****************************************************************************/
3272 {
3273  TRACE("iface %p, flags %#x.\n", iface, Flags);
3274 
3275  /* XXX: DDERR_INVALIDSURFACETYPE */
3276 
3277  switch (Flags)
3278  {
3279  case WINEDDGFS_CANFLIP:
3280  case WINEDDGFS_ISFLIPDONE:
3281  return DD_OK;
3282 
3283  default:
3284  return DDERR_INVALIDPARAMS;
3285  }
3286 }
3287 
3288 static HRESULT WINAPI ddraw_surface4_GetFlipStatus(IDirectDrawSurface4 *iface, DWORD flags)
3289 {
3290  struct ddraw_surface *surface = impl_from_IDirectDrawSurface4(iface);
3291 
3292  TRACE("iface %p, flags %#x.\n", iface, flags);
3293 
3295 }
3296 
3297 static HRESULT WINAPI ddraw_surface3_GetFlipStatus(IDirectDrawSurface3 *iface, DWORD flags)
3298 {
3299  struct ddraw_surface *surface = impl_from_IDirectDrawSurface3(iface);
3300 
3301  TRACE("iface %p, flags %#x.\n", iface, flags);
3302 
3304 }
3305 
3306 static HRESULT WINAPI ddraw_surface2_GetFlipStatus(IDirectDrawSurface2 *iface, DWORD flags)
3307 {
3308  struct ddraw_surface *surface = impl_from_IDirectDrawSurface2(iface);
3309 
3310  TRACE("iface %p, flags %#x.\n", iface, flags);
3311 
3313 }
3314 
3315 static HRESULT WINAPI ddraw_surface1_GetFlipStatus(IDirectDrawSurface *iface, DWORD flags)
3316 {
3317  struct ddraw_surface *surface = impl_from_IDirectDrawSurface(iface);
3318 
3319  TRACE("iface %p, flags %#x.\n", iface, flags);
3320 
3322 }
3323 
3324 /*****************************************************************************
3325  * IDirectDrawSurface7::GetOverlayPosition
3326  *
3327  * Returns the display coordinates of a visible and active overlay surface
3328  *
3329  * Params:
3330  * X
3331  * Y
3332  *
3333  * Returns:
3334  * DDERR_NOTAOVERLAYSURFACE, because it's a stub
3335  *****************************************************************************/
3337 {
3338  struct ddraw_surface *surface = impl_from_IDirectDrawSurface7(iface);
3339  HRESULT hr;
3340 
3341  TRACE("iface %p, x %p, y %p.\n", iface, x, y);
3342 
3345  surface->sub_resource_idx, x, y);
3347 
3348  return hr;
3349 }
3350 
3351 static HRESULT WINAPI ddraw_surface4_GetOverlayPosition(IDirectDrawSurface4 *iface, LONG *x, LONG *y)
3352 {
3353  struct ddraw_surface *surface = impl_from_IDirectDrawSurface4(iface);
3354 
3355  TRACE("iface %p, x %p, y %p.\n", iface, x, y);
3356 
3358 }
3359 
3360 static HRESULT WINAPI ddraw_surface3_GetOverlayPosition(IDirectDrawSurface3 *iface, LONG *x, LONG *y)
3361 {
3362  struct ddraw_surface *surface = impl_from_IDirectDrawSurface3(iface);
3363 
3364  TRACE("iface %p, x %p, y %p.\n", iface, x, y);
3365 
3367 }
3368 
3369 static HRESULT WINAPI ddraw_surface2_GetOverlayPosition(IDirectDrawSurface2 *iface, LONG *x, LONG *y)
3370 {
3371  struct ddraw_surface *surface = impl_from_IDirectDrawSurface2(iface);
3372 
3373  TRACE("iface %p, x %p, y %p.\n", iface, x, y);
3374 
3376 }
3377 
3378 static HRESULT WINAPI ddraw_surface1_GetOverlayPosition(IDirectDrawSurface *iface, LONG *x, LONG *y)
3379 {
3380  struct ddraw_surface *surface = impl_from_IDirectDrawSurface(iface);
3381 
3382  TRACE("iface %p, x %p, y %p.\n", iface, x, y);
3383 
3385 }
3386 
3387 /*****************************************************************************
3388  * IDirectDrawSurface7::GetPixelFormat
3389  *
3390  * Returns the pixel format of the Surface
3391  *
3392  * Params:
3393  * PixelFormat: Pointer to a DDPIXELFORMAT structure to which the pixel
3394  * format should be written
3395  *
3396  * Returns:
3397  * DD_OK on success
3398  * DDERR_INVALIDPARAMS if PixelFormat is NULL
3399  *
3400  *****************************************************************************/
3402 {
3403  /* What is DDERR_INVALIDSURFACETYPE for here? */
3404  struct ddraw_surface *surface = impl_from_IDirectDrawSurface7(iface);
3405 
3406  TRACE("iface %p, pixel_format %p.\n", iface, PixelFormat);
3407 
3408  if(!PixelFormat)
3409  return DDERR_INVALIDPARAMS;
3410 
3414 
3415  return DD_OK;
3416 }
3417 
3419 {
3420  struct ddraw_surface *surface = impl_from_IDirectDrawSurface4(iface);
3421 
3422  TRACE("iface %p, pixel_format %p.\n", iface, pixel_format);
3423 
3425 }
3426 
3428 {
3429  struct ddraw_surface *surface = impl_from_IDirectDrawSurface3(iface);
3430 
3431  TRACE("iface %p, pixel_format %p.\n", iface, pixel_format);
3432 
3434 }
3435 
3437 {
3438  struct ddraw_surface *surface = impl_from_IDirectDrawSurface2(iface);
3439 
3440  TRACE("iface %p, pixel_format %p.\n", iface, pixel_format);
3441 
3443 }
3444 
3446 {
3447  struct ddraw_surface *surface = impl_from_IDirectDrawSurface(iface);
3448 
3449  TRACE("iface %p, pixel_format %p.\n", iface, pixel_format);
3450 
3452 }
3453 
3454 /*****************************************************************************
3455  * IDirectDrawSurface7::GetSurfaceDesc
3456  *
3457  * Returns the description of this surface
3458  *
3459  * Params:
3460  * DDSD: Address of a DDSURFACEDESC2 structure that is to be filled with the
3461  * surface desc
3462  *
3463  * Returns:
3464  * DD_OK on success
3465  * DDERR_INVALIDPARAMS if DDSD is NULL
3466  *
3467  *****************************************************************************/
3469 {
3470  struct ddraw_surface *surface = impl_from_IDirectDrawSurface7(iface);
3471 
3472  TRACE("iface %p, surface_desc %p.\n", iface, DDSD);
3473 
3474  if(!DDSD)
3475  return DDERR_INVALIDPARAMS;
3476 
3477  if (DDSD->dwSize != sizeof(DDSURFACEDESC2))
3478  {
3479  WARN("Incorrect struct size %d, returning DDERR_INVALIDPARAMS\n",DDSD->dwSize);
3480  return DDERR_INVALIDPARAMS;
3481  }
3482 
3484  DD_STRUCT_COPY_BYSIZE(DDSD, &surface->surface_desc);
3485  TRACE("Returning surface desc:\n");
3488 
3489  return DD_OK;
3490 }
3491 
3492 static HRESULT WINAPI ddraw_surface4_GetSurfaceDesc(IDirectDrawSurface4 *iface, DDSURFACEDESC2 *DDSD)
3493 {
3494  struct ddraw_surface *surface = impl_from_IDirectDrawSurface4(iface);
3495 
3496  TRACE("iface %p, surface_desc %p.\n", iface, DDSD);
3497 
3499 }
3500 
3502 {
3503  struct ddraw_surface *surface = impl_from_IDirectDrawSurface3(iface);
3504 
3505  TRACE("iface %p, surface_desc %p.\n", iface, surface_desc);
3506 
3507  if (!surface_desc) return DDERR_INVALIDPARAMS;
3508 
3509  if (surface_desc->dwSize != sizeof(DDSURFACEDESC))
3510  {
3511  WARN("Incorrect structure size %u, returning DDERR_INVALIDPARAMS.\n", surface_desc->dwSize);
3512  return DDERR_INVALIDPARAMS;
3513  }
3514 
3517  TRACE("Returning surface desc:\n");
3518  if (TRACE_ON(ddraw))
3519  {
3520  /* DDRAW_dump_surface_desc handles the smaller size */
3522  }
3524 
3525  return DD_OK;
3526 }
3527 
3528 static HRESULT WINAPI ddraw_surface2_GetSurfaceDesc(IDirectDrawSurface2 *iface, DDSURFACEDESC *DDSD)
3529 {
3530  struct ddraw_surface *surface = impl_from_IDirectDrawSurface2(iface);
3531 
3532  TRACE("iface %p, surface_desc %p.\n", iface, DDSD);
3533 
3535 }
3536 
3537 static HRESULT WINAPI ddraw_surface1_GetSurfaceDesc(IDirectDrawSurface *iface, DDSURFACEDESC *DDSD)
3538 {
3539  struct ddraw_surface *surface = impl_from_IDirectDrawSurface(iface);
3540 
3541  TRACE("iface %p, surface_desc %p.\n", iface, DDSD);
3542 
3544 }
3545 
3546 /*****************************************************************************
3547  * IDirectDrawSurface7::Initialize
3548  *
3549  * Initializes the surface. This is a no-op in Wine
3550  *
3551  * Params:
3552  * DD: Pointer to an DirectDraw interface
3553  * DDSD: Surface description for initialization
3554  *
3555  * Returns:
3556  * DDERR_ALREADYINITIALIZED
3557  *
3558  *****************************************************************************/
3560  IDirectDraw *ddraw, DDSURFACEDESC2 *surface_desc)
3561 {
3562  TRACE("iface %p, ddraw %p, surface_desc %p.\n", iface, ddraw, surface_desc);
3563 
3564  return DDERR_ALREADYINITIALIZED;
3565 }
3566 
3567 static HRESULT WINAPI ddraw_surface4_Initialize(IDirectDrawSurface4 *iface,
3568  IDirectDraw *ddraw, DDSURFACEDESC2 *surface_desc)
3569 {
3570  struct ddraw_surface *surface = impl_from_IDirectDrawSurface4(iface);
3571 
3572  TRACE("iface %p, ddraw %p, surface_desc %p.\n", iface, ddraw, surface_desc);
3573 
3575  ddraw, surface_desc);
3576 }
3577 
3578 static HRESULT WINAPI ddraw_surface3_Initialize(IDirectDrawSurface3 *iface,
3579  IDirectDraw *ddraw, DDSURFACEDESC *surface_desc)
3580 {
3581  struct ddraw_surface *surface = impl_from_IDirectDrawSurface3(iface);
3582  DDSURFACEDESC2 surface_desc2;
3583 
3584  TRACE("iface %p, ddraw %p, surface_desc %p.\n", iface, ddraw, surface_desc);
3585 
3586  if (surface_desc) DDSD_to_DDSD2(surface_desc, &surface_desc2);
3588  ddraw, surface_desc ? &surface_desc2 : NULL);
3589 }
3590 
3591 static HRESULT WINAPI ddraw_surface2_Initialize(IDirectDrawSurface2 *iface,
3592  IDirectDraw *ddraw, DDSURFACEDESC *surface_desc)
3593 {
3594  struct ddraw_surface *surface = impl_from_IDirectDrawSurface2(iface);
3595  DDSURFACEDESC2 surface_desc2;
3596 
3597  TRACE("iface %p, ddraw %p, surface_desc %p.\n", iface, ddraw, surface_desc);
3598 
3599  if (surface_desc) DDSD_to_DDSD2(surface_desc, &surface_desc2);
3601  ddraw, surface_desc ? &surface_desc2 : NULL);
3602 }
3603 
3604 static HRESULT WINAPI ddraw_surface1_Initialize(IDirectDrawSurface *iface,
3605  IDirectDraw *ddraw, DDSURFACEDESC *surface_desc)
3606 {
3607  struct ddraw_surface *surface = impl_from_IDirectDrawSurface(iface);
3608  DDSURFACEDESC2 surface_desc2;
3609 
3610  TRACE("iface %p, ddraw %p, surface_desc %p.\n", iface, ddraw, surface_desc);
3611 
3612  if (surface_desc) DDSD_to_DDSD2(surface_desc, &surface_desc2);
3614  ddraw, surface_desc ? &surface_desc2 : NULL);
3615 }
3616 
3617 /*****************************************************************************
3618  * IDirect3DTexture1::Initialize
3619  *
3620  * The sdk says it's not implemented
3621  *
3622  * Params:
3623  * ?
3624  *
3625  * Returns
3626  * DDERR_UNSUPPORTED
3627  *
3628  *****************************************************************************/
3629 static HRESULT WINAPI d3d_texture1_Initialize(IDirect3DTexture *iface,
3630  IDirect3DDevice *device, IDirectDrawSurface *surface)
3631 {
3632  TRACE("iface %p, device %p, surface %p.\n", iface, device, surface);
3633 
3634  return DDERR_UNSUPPORTED; /* Unchecked */
3635 }
3636 
3637 /*****************************************************************************
3638  * IDirectDrawSurface7::IsLost
3639  *
3640  * Checks if the surface is lost
3641  *
3642  * Returns:
3643  * DD_OK, if the surface is usable
3644  * DDERR_ISLOST if the surface is lost
3645  *
3646  *****************************************************************************/
3648 {
3649  struct ddraw_surface *surface = impl_from_IDirectDrawSurface7(iface);
3650 
3651  TRACE("iface %p.\n", iface);
3652 
3653  if (surface->ddraw->device_state != DDRAW_DEVICE_STATE_OK || surface->is_lost)
3654  return DDERR_SURFACELOST;
3655 
3656  return DD_OK;
3657 }
3658 
3659 static HRESULT WINAPI ddraw_surface4_IsLost(IDirectDrawSurface4 *iface)
3660 {
3661  struct ddraw_surface *surface = impl_from_IDirectDrawSurface4(iface);
3662 
3663  TRACE("iface %p.\n", iface);
3664 
3666 }
3667 
3668 static HRESULT WINAPI ddraw_surface3_IsLost(IDirectDrawSurface3 *iface)
3669 {
3670  struct ddraw_surface *surface = impl_from_IDirectDrawSurface3(iface);
3671 
3672  TRACE("iface %p.\n", iface);
3673 
3675 }
3676 
3677 static HRESULT WINAPI ddraw_surface2_IsLost(IDirectDrawSurface2 *iface)
3678 {
3679  struct ddraw_surface *surface = impl_from_IDirectDrawSurface2(iface);
3680 
3681  TRACE("iface %p.\n", iface);
3682 
3684 }
3685 
3686 static HRESULT WINAPI ddraw_surface1_IsLost(IDirectDrawSurface *iface)
3687 {
3688  struct ddraw_surface *surface = impl_from_IDirectDrawSurface(iface);
3689 
3690  TRACE("iface %p.\n", iface);
3691 
3693 }
3694 
3695 /*****************************************************************************
3696  * IDirectDrawSurface7::Restore
3697  *
3698  * Restores a lost surface. This makes the surface usable again, but
3699  * doesn't reload its old contents
3700  *
3701  * Returns:
3702  * DD_OK on success, error code otherwise.
3703  *
3704  *****************************************************************************/
3706 {
3707  struct ddraw_surface *surface = impl_from_IDirectDrawSurface7(iface);
3708 
3709  TRACE("iface %p.\n", iface);
3710 
3712  {
3713  struct wined3d_swapchain *swapchain = surface->ddraw->wined3d_swapchain;
3714  struct wined3d_sub_resource_desc wined3d_desc;
3715  struct wined3d_display_mode mode;
3716  HRESULT hr;
3717 
3718  if (FAILED(hr = wined3d_swapchain_get_display_mode(swapchain, &mode, NULL)))
3719  {
3720  WARN("Failed to get display mode, hr %#x.\n", hr);
3721  return hr;
3722  }
3723 
3724  if (FAILED(hr = wined3d_texture_get_sub_resource_desc(surface->wined3d_texture, 0, &wined3d_desc)))
3725  {
3726  WARN("Failed to get resource desc, hr %#x.\n", hr);
3727  return hr;
3728  }
3729 
3730  if (mode.width != wined3d_desc.width || mode.height != wined3d_desc.height)
3731  {
3732  WARN("Display mode dimensions %ux%u don't match surface dimensions %ux%u.\n",
3733  mode.width, mode.height, wined3d_desc.width, wined3d_desc.height);
3734  return DDERR_WRONGMODE;
3735  }
3736 
3737  if (mode.format_id != wined3d_desc.format)
3738  {
3739  WARN("Display mode format %#x doesn't match surface format %#x.\n",
3740  mode.format_id, wined3d_desc.format);
3741  return DDERR_WRONGMODE;
3742  }
3743  }
3744 
3746  surface->is_lost = FALSE;
3747 
3748  return DD_OK;
3749 }
3750 
3751 static HRESULT WINAPI ddraw_surface4_Restore(IDirectDrawSurface4 *iface)
3752 {
3753  struct ddraw_surface *surface = impl_from_IDirectDrawSurface4(iface);
3754 
3755  TRACE("iface %p.\n", iface);
3756 
3758 }
3759 
3760 static HRESULT WINAPI ddraw_surface3_Restore(IDirectDrawSurface3 *iface)
3761 {
3762  struct ddraw_surface *surface = impl_from_IDirectDrawSurface3(iface);
3763 
3764  TRACE("iface %p.\n", iface);
3765 
3767 }
3768 
3769 static HRESULT WINAPI ddraw_surface2_Restore(IDirectDrawSurface2 *iface)
3770 {
3771  struct ddraw_surface *surface = impl_from_IDirectDrawSurface2(iface);
3772 
3773  TRACE("iface %p.\n", iface);
3774 
3776 }
3777 
3778 static HRESULT WINAPI ddraw_surface1_Restore(IDirectDrawSurface *iface)
3779 {
3780  struct ddraw_surface *surface = impl_from_IDirectDrawSurface(iface);
3781 
3782  TRACE("iface %p.\n", iface);
3783 
3785 }
3786 
3787 /*****************************************************************************
3788  * IDirectDrawSurface7::SetOverlayPosition
3789  *
3790  * Changes the display coordinates of an overlay surface
3791  *
3792  * Params:
3793  * X:
3794  * Y:
3795  *
3796  * Returns:
3797  * DDERR_NOTAOVERLAYSURFACE, because we don't support overlays right now
3798  *****************************************************************************/
3800 {
3801  struct ddraw_surface *surface = impl_from_IDirectDrawSurface7(iface);
3802  HRESULT hr;
3803 
3804  TRACE("iface %p, x %d, y %d.\n", iface, x, y);
3805 
3808  surface->sub_resource_idx, x, y);
3810 
3811  return hr;
3812 }
3813 
3814 static HRESULT WINAPI ddraw_surface4_SetOverlayPosition(IDirectDrawSurface4 *iface, LONG x, LONG y)
3815 {
3816  struct ddraw_surface *surface = impl_from_IDirectDrawSurface4(iface);
3817 
3818  TRACE("iface %p, x %d, y %d.\n", iface, x, y);
3819 
3821 }
3822 
3823 static HRESULT WINAPI ddraw_surface3_SetOverlayPosition(IDirectDrawSurface3 *iface, LONG x, LONG y)
3824 {
3825  struct ddraw_surface *surface = impl_from_IDirectDrawSurface3(iface);
3826 
3827  TRACE("iface %p, x %d, y %d.\n", iface, x, y);
3828 
3830 }
3831 
3832 static HRESULT WINAPI ddraw_surface2_SetOverlayPosition(IDirectDrawSurface2 *iface, LONG x, LONG y)
3833 {
3834  struct ddraw_surface *surface = impl_from_IDirectDrawSurface2(iface);
3835 
3836  TRACE("iface %p, x %d, y %d.\n", iface, x, y);
3837 
3839 }
3840 
3841 static HRESULT WINAPI ddraw_surface1_SetOverlayPosition(IDirectDrawSurface *iface, LONG x, LONG y)
3842 {
3843  struct ddraw_surface *surface = impl_from_IDirectDrawSurface(iface);
3844 
3845  TRACE("iface %p, x %d, y %d.\n", iface, x, y);
3846 
3848 }
3849 
3850 /*****************************************************************************
3851  * IDirectDrawSurface7::UpdateOverlay
3852  *
3853  * Modifies the attributes of an overlay surface.
3854  *
3855  * Params:
3856  * SrcRect: The section of the source being used for the overlay
3857  * DstSurface: Address of the surface that is overlaid
3858  * DstRect: Place of the overlay
3859  * Flags: some DDOVER_* flags
3860  *
3861  * Returns:
3862  * DDERR_UNSUPPORTED, because we don't support overlays
3863  *
3864  *****************************************************************************/
3866  IDirectDrawSurface7 *dst_surface, RECT *dst_rect, DWORD flags, DDOVERLAYFX *fx)
3867 {
3868  struct ddraw_surface *src_impl = impl_from_IDirectDrawSurface7(iface);
3869  struct ddraw_surface *dst_impl = unsafe_impl_from_IDirectDrawSurface7(dst_surface);
3870  struct wined3d_texture *dst_wined3d_texture = NULL;
3871  unsigned int dst_sub_resource_idx = 0;
3872  HRESULT hr;
3873 
3874  TRACE("iface %p, src_rect %s, dst_surface %p, dst_rect %s, flags %#x, fx %p.\n",
3875  iface, wine_dbgstr_rect(src_rect), dst_surface, wine_dbgstr_rect(dst_rect), flags, fx);
3876 
3877  if (fx)
3878  FIXME("Ignoring fx %p.\n", fx);
3879 
3881  if (dst_impl)
3882  {
3883  dst_wined3d_texture = dst_impl->wined3d_texture;
3884  dst_sub_resource_idx = dst_impl->sub_resource_idx;
3885  }
3887  src_rect, dst_wined3d_texture, dst_sub_resource_idx, dst_rect, flags);
3889 
3890  switch (hr)
3891  {
3895  default:
3896  return hr;
3897  }
3898 }
3899 
3900 static HRESULT WINAPI ddraw_surface4_UpdateOverlay(IDirectDrawSurface4 *iface, RECT *src_rect,
3901  IDirectDrawSurface4 *dst_surface, RECT *dst_rect, DWORD flags, DDOVERLAYFX *fx)
3902 {
3903  struct ddraw_surface *src_impl = impl_from_IDirectDrawSurface4(iface);
3904  struct ddraw_surface *dst_impl = unsafe_impl_from_IDirectDrawSurface4(dst_surface);
3905 
3906  TRACE("iface %p, src_rect %s, dst_surface %p, dst_rect %s, flags %#x, fx %p.\n",
3907  iface, wine_dbgstr_rect(src_rect), dst_surface, wine_dbgstr_rect(dst_rect), flags, fx);
3908 
3909  return ddraw_surface7_UpdateOverlay(&src_impl->IDirectDrawSurface7_iface, src_rect,
3910  dst_impl ? &dst_impl->IDirectDrawSurface7_iface : NULL, dst_rect, flags, fx);
3911 }
3912 
3913 static HRESULT WINAPI ddraw_surface3_UpdateOverlay(IDirectDrawSurface3 *iface, RECT *src_rect,
3914  IDirectDrawSurface3 *dst_surface, RECT *dst_rect, DWORD flags, DDOVERLAYFX *fx)
3915 {
3916  struct ddraw_surface *src_impl = impl_from_IDirectDrawSurface3(iface);
3917  struct ddraw_surface *dst_impl = unsafe_impl_from_IDirectDrawSurface3(dst_surface);
3918 
3919  TRACE("iface %p, src_rect %s, dst_surface %p, dst_rect %s, flags %#x, fx %p.\n",
3920  iface, wine_dbgstr_rect(src_rect), dst_surface, wine_dbgstr_rect(dst_rect), flags, fx);
3921 
3922  return ddraw_surface7_UpdateOverlay(&src_impl->IDirectDrawSurface7_iface, src_rect,
3923  dst_impl ? &dst_impl->IDirectDrawSurface7_iface : NULL, dst_rect, flags, fx);
3924 }
3925 
3926 static HRESULT WINAPI ddraw_surface2_UpdateOverlay(IDirectDrawSurface2 *iface, RECT *src_rect,
3927  IDirectDrawSurface2 *dst_surface, RECT *dst_rect, DWORD flags, DDOVERLAYFX *fx)
3928 {
3929  struct ddraw_surface *src_impl = impl_from_IDirectDrawSurface2(iface);
3930  struct ddraw_surface *dst_impl = unsafe_impl_from_IDirectDrawSurface2(dst_surface);
3931 
3932  TRACE("iface %p, src_rect %s, dst_surface %p, dst_rect %s, flags %#x, fx %p.\n",
3933  iface, wine_dbgstr_rect(src_rect), dst_surface, wine_dbgstr_rect(dst_rect), flags, fx);
3934 
3935  return ddraw_surface7_UpdateOverlay(&src_impl->IDirectDrawSurface7_iface, src_rect,
3936  dst_impl ? &dst_impl->IDirectDrawSurface7_iface : NULL, dst_rect, flags, fx);
3937 }
3938 
3939 static HRESULT WINAPI ddraw_surface1_UpdateOverlay(IDirectDrawSurface *iface, RECT *src_rect,
3940  IDirectDrawSurface *dst_surface, RECT *dst_rect, DWORD flags, DDOVERLAYFX *fx)
3941 {
3942  struct ddraw_surface *src_impl = impl_from_IDirectDrawSurface(iface);
3943  struct ddraw_surface *dst_impl = unsafe_impl_from_IDirectDrawSurface(dst_surface);
3944 
3945  TRACE("iface %p, src_rect %s, dst_surface %p, dst_rect %s, flags %#x, fx %p.\n",
3946  iface, wine_dbgstr_rect(src_rect), dst_surface, wine_dbgstr_rect(dst_rect), flags, fx);
3947 
3948  return ddraw_surface7_UpdateOverlay(&src_impl->IDirectDrawSurface7_iface, src_rect,
3949  dst_impl ? &dst_impl->IDirectDrawSurface7_iface : NULL, dst_rect, flags, fx);
3950 }
3951 
3952 /*****************************************************************************
3953  * IDirectDrawSurface7::UpdateOverlayDisplay
3954  *
3955  * The DX7 sdk says that it's not implemented
3956  *
3957  * Params:
3958  * Flags: ?
3959  *
3960  * Returns: DDERR_UNSUPPORTED, because we don't support overlays
3961  *
3962  *****************************************************************************/
3964 {
3965  TRACE("iface %p, flags %#x.\n", iface, Flags);
3966 
3967  return DDERR_UNSUPPORTED;
3968 }
3969 
3970 static HRESULT WINAPI ddraw_surface4_UpdateOverlayDisplay(IDirectDrawSurface4 *iface, DWORD flags)
3971 {
3972  struct ddraw_surface *surface = impl_from_IDirectDrawSurface4(iface);
3973 
3974  TRACE("iface %p, flags %#x.\n", iface, flags);
3975 
3977 }
3978 
3979 static HRESULT WINAPI ddraw_surface3_UpdateOverlayDisplay(IDirectDrawSurface3 *iface, DWORD flags)
3980 {
3981  struct ddraw_surface *surface = impl_from_IDirectDrawSurface3(iface);
3982 
3983  TRACE("iface %p, flags %#x.\n", iface, flags);
3984 
3986 }
3987 
3988 static HRESULT WINAPI ddraw_surface2_UpdateOverlayDisplay(IDirectDrawSurface2 *iface, DWORD flags)
3989 {
3990  struct ddraw_surface *surface = impl_from_IDirectDrawSurface2(iface);
3991 
3992  TRACE("iface %p, flags %#x.\n", iface, flags);
3993 
3995 }
3996 
3998 {
3999  struct ddraw_surface *surface = impl_from_IDirectDrawSurface(iface);
4000 
4001  TRACE("iface %p, flags %#x.\n", iface, flags);
4002 
4004 }
4005 
4006 /*****************************************************************************
4007  * IDirectDrawSurface7::UpdateOverlayZOrder
4008  *
4009  * Sets an overlay's Z order
4010  *
4011  * Params:
4012  * Flags: DDOVERZ_* flags
4013  * DDSRef: Defines the relative position in the overlay chain
4014  *
4015  * Returns:
4016  * DDERR_NOTOVERLAYSURFACE, because we don't support overlays
4017  *
4018  *****************************************************************************/
4021 {
4022  struct ddraw_surface *surface = impl_from_IDirectDrawSurface7(iface);
4023 
4024  FIXME("iface %p, flags %#x, reference %p stub!\n", iface, flags, reference);
4025 
4027  if (!(surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_OVERLAY))
4028  {
4029  WARN("Not an overlay surface.\n");
4031  return DDERR_NOTAOVERLAYSURFACE;
4032  }
4034 
4035  return DD_OK;
4036 }
4037 
4038 static HRESULT WINAPI ddraw_surface4_UpdateOverlayZOrder(IDirectDrawSurface4 *iface,
4039  DWORD flags, IDirectDrawSurface4 *reference)
4040 {
4041  struct ddraw_surface *surface = impl_from_IDirectDrawSurface4(iface);
4043 
4044  TRACE("iface %p, flags %#x, reference %p.\n", iface, flags, reference);
4045 
4047  reference_impl ? &reference_impl->IDirectDrawSurface7_iface : NULL);
4048 }
4049 
4050 static HRESULT WINAPI ddraw_surface3_UpdateOverlayZOrder(IDirectDrawSurface3 *iface,
4051  DWORD flags, IDirectDrawSurface3 *reference)
4052 {
4053  struct ddraw_surface *surface = impl_from_IDirectDrawSurface3(iface);
4055 
4056  TRACE("iface %p, flags %#x, reference %p.\n", iface, flags, reference);
4057 
4059  reference_impl ? &reference_impl->IDirectDrawSurface7_iface : NULL);
4060 }
4061 
4062 static HRESULT WINAPI ddraw_surface2_UpdateOverlayZOrder(IDirectDrawSurface2 *iface,
4063  DWORD flags, IDirectDrawSurface2 *reference)
4064 {
4065  struct ddraw_surface *surface = impl_from_IDirectDrawSurface2(iface);
4067 
4068  TRACE("iface %p, flags %#x, reference %p.\n", iface, flags, reference);
4069 
4071  reference_impl ? &reference_impl->IDirectDrawSurface7_iface : NULL);
4072 }
4073 
4074 static HRESULT WINAPI ddraw_surface1_UpdateOverlayZOrder(IDirectDrawSurface *iface,
4075  DWORD flags, IDirectDrawSurface *reference)
4076 {
4077  struct ddraw_surface *surface = impl_from_IDirectDrawSurface(iface);
4079 
4080  TRACE("iface %p, flags %#x, reference %p.\n", iface, flags, reference);
4081 
4083  reference_impl ? &reference_impl->IDirectDrawSurface7_iface : NULL);
4084 }
4085 
4086 /*****************************************************************************
4087  * IDirectDrawSurface7::GetDDInterface
4088  *
4089  * Returns the IDirectDraw7 interface pointer of the DirectDraw object this
4090  * surface belongs to
4091  *
4092  * Params:
4093  * DD: Address to write the interface pointer to
4094  *
4095  * Returns:
4096  * DD_OK on success
4097  * DDERR_INVALIDPARAMS if DD is NULL
4098  *
4099  *****************************************************************************/
4101 {
4103 
4104  TRACE("iface %p, ddraw %p.\n", iface, DD);
4105 
4106  if(!DD)
4107  return DDERR_INVALIDPARAMS;
4108 
4109  switch(This->version)
4110  {
4111  case 7:
4112  *DD = &This->ddraw->IDirectDraw7_iface;
4113  break;
4114 
4115  case 4:
4116  *DD = &This->ddraw->IDirectDraw4_iface;
4117  break;
4118 
4119  case 2:
4120  *DD = &This->ddraw->IDirectDraw2_iface;
4121  break;
4122 
4123  case 1:
4124  *DD = &This->ddraw->IDirectDraw_iface;
4125  break;
4126 
4127  }
4128  IUnknown_AddRef((IUnknown *)*DD);
4129 
4130  return DD_OK;
4131 }
4132 
4133 static HRESULT WINAPI ddraw_surface4_GetDDInterface(IDirectDrawSurface4 *iface, void **ddraw)
4134 {
4135  struct ddraw_surface *surface = impl_from_IDirectDrawSurface4(iface);
4136 
4137  TRACE("iface %p, ddraw %p.\n", iface, ddraw);
4138 
4140 }
4141 
4142 static HRESULT WINAPI ddraw_surface3_GetDDInterface(IDirectDrawSurface3 *iface, void **ddraw)
4143 {
4144  struct ddraw_surface *surface = impl_from_IDirectDrawSurface3(iface);
4145 
4146  TRACE("iface %p, ddraw %p.\n", iface, ddraw);
4147 
4149 }
4150 
4151 static HRESULT WINAPI ddraw_surface2_GetDDInterface(IDirectDrawSurface2 *iface, void **ddraw)
4152 {
4153  struct ddraw_surface *surface = impl_from_IDirectDrawSurface2(iface);
4154 
4155  TRACE("iface %p, ddraw %p.\n", iface, ddraw);
4156 
4158 }
4159 
4161 {
4162  TRACE("iface %p.\n", iface);
4163 
4164  return DD_OK;
4165 }
4166 
4167 static HRESULT WINAPI ddraw_surface4_ChangeUniquenessValue(IDirectDrawSurface4 *iface)
4168 {
4169  struct ddraw_surface *surface = impl_from_IDirectDrawSurface4(iface);
4170 
4171  TRACE("iface %p.\n", iface);
4172 
4174 }
4175 
4177 {
4178  TRACE("iface %p, value %p.\n", iface, pValue);
4179 
4180  *pValue = 0;
4181 
4182  return DD_OK;
4183 }
4184 
4185 static HRESULT WINAPI ddraw_surface4_GetUniquenessValue(IDirectDrawSurface4 *iface, DWORD *pValue)
4186 {
4187  struct ddraw_surface *surface = impl_from_IDirectDrawSurface4(iface);
4188 
4189  TRACE("iface %p, value %p.\n", iface, pValue);
4190 
4192 }
4193 
4194 /*****************************************************************************
4195  * IDirectDrawSurface7::SetLOD
4196  *
4197  * Sets the level of detail of a texture
4198  *
4199  * Params:
4200  * MaxLOD: LOD to set
4201  *
4202  * Returns:
4203  * DD_OK on success
4204  * DDERR_INVALIDOBJECT if the surface is invalid for this method
4205  *
4206  *****************************************************************************/
4208 {
4209  struct ddraw_surface *surface = impl_from_IDirectDrawSurface7(iface);
4210  HRESULT hr;
4211 
4212  TRACE("iface %p, lod %u.\n", iface, MaxLOD);
4213 
4216  {
4218  return DDERR_INVALIDOBJECT;
4219  }
4220 
4221  hr = wined3d_texture_set_lod(surface->wined3d_texture, MaxLOD);
4223 
4224  return hr;
4225 }
4226 
4227 /*****************************************************************************
4228  * IDirectDrawSurface7::GetLOD
4229  *
4230  * Returns the level of detail of a Direct3D texture
4231  *
4232  * Params:
4233  * MaxLOD: Address to write the LOD to
4234  *
4235  * Returns:
4236  * DD_OK on success
4237  * DDERR_INVALIDPARAMS if MaxLOD is NULL
4238  * DDERR_INVALIDOBJECT if the surface is invalid for this method
4239  *
4240  *****************************************************************************/
4242 {
4243  struct ddraw_surface *surface = impl_from_IDirectDrawSurface7(iface);
4244 
4245  TRACE("iface %p, lod %p.\n", iface, MaxLOD);
4246 
4247  if(!MaxLOD)
4248  return DDERR_INVALIDPARAMS;
4249 
4252  {
4254  return DDERR_INVALIDOBJECT;
4255  }
4256 
4257  *MaxLOD = wined3d_texture_get_lod(surface->wined3d_texture);
4259 
4260  return DD_OK;
4261 }
4262 
4263 /*****************************************************************************
4264  * IDirectDrawSurface7::BltFast
4265  *
4266  * Performs a fast Blit.
4267  *
4268  * Params:
4269  * dstx: The x coordinate to blit to on the destination
4270  * dsty: The y coordinate to blit to on the destination
4271  * Source: The source surface
4272  * rsrc: The source rectangle
4273  * trans: Type of transfer. Some DDBLTFAST_* flags
4274  *
4275  * Returns:
4276  * DD_OK on success, error code otherwise.
4277  *
4278  *****************************************************************************/
4280  DWORD dst_x, DWORD dst_y, IDirectDrawSurface7 *src_surface, RECT *src_rect, DWORD trans)
4281 {
4282  struct ddraw_surface *dst_impl = impl_from_IDirectDrawSurface7(iface);
4283  struct ddraw_surface *src_impl = unsafe_impl_from_IDirectDrawSurface7(src_surface);
4285  DWORD src_w, src_h, dst_w, dst_h;
4286  HRESULT hr = DD_OK;
4287  RECT dst_rect, s;
4288 
4289  TRACE("iface %p, dst_x %u, dst_y %u, src_surface %p, src_rect %s, flags %#x.\n",
4290  iface, dst_x, dst_y, src_surface, wine_dbgstr_rect(src_rect), trans);
4291 
4292  dst_w = dst_impl->surface_desc.dwWidth;
4293  dst_h = dst_impl->surface_desc.dwHeight;
4294 
4295  if (!src_rect)
4296  {
4297  SetRect(&s, 0, 0, src_impl->surface_desc.dwWidth, src_impl->surface_desc.dwHeight);
4298  src_rect = &s;
4299  }
4300 
4301  src_w = src_rect->right - src_rect->