Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygensurface.c
Go to the documentation of this file.
00001 /* DirectDraw Surface Implementation 00002 * 00003 * Copyright (c) 1997-2000 Marcus Meissner 00004 * Copyright (c) 1998-2000 Lionel Ulmer 00005 * Copyright (c) 2000-2001 TransGaming Technologies Inc. 00006 * Copyright (c) 2006 Stefan Dösinger 00007 * Copyright (c) 2011 Ričardas Barkauskas for CodeWeavers 00008 * 00009 * This library is free software; you can redistribute it and/or 00010 * modify it under the terms of the GNU Lesser General Public 00011 * License as published by the Free Software Foundation; either 00012 * version 2.1 of the License, or (at your option) any later version. 00013 * 00014 * This library is distributed in the hope that it will be useful, 00015 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00016 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00017 * Lesser General Public License for more details. 00018 * 00019 * You should have received a copy of the GNU Lesser General Public 00020 * License along with this library; if not, write to the Free Software 00021 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 00022 */ 00023 00024 #include "config.h" 00025 #include "wine/port.h" 00026 00027 #include "ddraw_private.h" 00028 00029 WINE_DEFAULT_DEBUG_CHANNEL(ddraw); 00030 00031 static IDirectDrawSurfaceImpl *unsafe_impl_from_IDirectDrawSurface2(IDirectDrawSurface2 *iface); 00032 static IDirectDrawSurfaceImpl *unsafe_impl_from_IDirectDrawSurface3(IDirectDrawSurface3 *iface); 00033 00034 static inline IDirectDrawSurfaceImpl *impl_from_IDirectDrawGammaControl(IDirectDrawGammaControl *iface) 00035 { 00036 return CONTAINING_RECORD(iface, IDirectDrawSurfaceImpl, IDirectDrawGammaControl_iface); 00037 } 00038 00039 /* This is slow, of course. Also, in case of locks, we can't prevent other 00040 * applications from drawing to the screen while we've locked the frontbuffer. 00041 * We'd like to do this in wined3d instead, but for that to work wined3d needs 00042 * to support windowless rendering first. */ 00043 static HRESULT ddraw_surface_update_frontbuffer(IDirectDrawSurfaceImpl *surface, const RECT *rect, BOOL read) 00044 { 00045 HDC surface_dc, screen_dc; 00046 int x, y, w, h; 00047 HRESULT hr; 00048 BOOL ret; 00049 00050 if (!rect) 00051 { 00052 x = 0; 00053 y = 0; 00054 w = surface->surface_desc.dwWidth; 00055 h = surface->surface_desc.dwHeight; 00056 } 00057 else 00058 { 00059 x = rect->left; 00060 y = rect->top; 00061 w = rect->right - rect->left; 00062 h = rect->bottom - rect->top; 00063 } 00064 00065 if (w <= 0 || h <= 0) 00066 return DD_OK; 00067 00068 if (surface->ddraw->swapchain_window) 00069 { 00070 /* Nothing to do, we control the frontbuffer, or at least the parts we 00071 * care about. */ 00072 if (read) 00073 return DD_OK; 00074 00075 return wined3d_surface_blt(surface->ddraw->wined3d_frontbuffer, rect, 00076 surface->wined3d_surface, rect, 0, NULL, WINED3D_TEXF_POINT); 00077 } 00078 00079 if (FAILED(hr = wined3d_surface_getdc(surface->wined3d_surface, &surface_dc))) 00080 { 00081 ERR("Failed to get surface DC, hr %#x.\n", hr); 00082 return hr; 00083 } 00084 00085 if (!(screen_dc = GetDC(NULL))) 00086 { 00087 wined3d_surface_releasedc(surface->wined3d_surface, surface_dc); 00088 ERR("Failed to get screen DC.\n"); 00089 return E_FAIL; 00090 } 00091 00092 if (read) 00093 ret = BitBlt(surface_dc, x, y, w, h, 00094 screen_dc, x, y, SRCCOPY); 00095 else 00096 ret = BitBlt(screen_dc, x, y, w, h, 00097 surface_dc, x, y, SRCCOPY); 00098 00099 ReleaseDC(NULL, screen_dc); 00100 wined3d_surface_releasedc(surface->wined3d_surface, surface_dc); 00101 00102 if (!ret) 00103 { 00104 ERR("Failed to blit to/from screen.\n"); 00105 return E_FAIL; 00106 } 00107 00108 return DD_OK; 00109 } 00110 00111 /***************************************************************************** 00112 * IUnknown parts follow 00113 *****************************************************************************/ 00114 00115 /***************************************************************************** 00116 * IDirectDrawSurface7::QueryInterface 00117 * 00118 * A normal QueryInterface implementation. For QueryInterface rules 00119 * see ddraw.c, IDirectDraw7::QueryInterface. This method 00120 * can Query IDirectDrawSurface interfaces in all version, IDirect3DTexture 00121 * in all versions, the IDirectDrawGammaControl interface and it can 00122 * create an IDirect3DDevice. (Uses IDirect3D7::CreateDevice) 00123 * 00124 * Params: 00125 * riid: The interface id queried for 00126 * obj: Address to write the pointer to 00127 * 00128 * Returns: 00129 * S_OK on success 00130 * E_NOINTERFACE if the requested interface wasn't found 00131 * 00132 *****************************************************************************/ 00133 static HRESULT WINAPI ddraw_surface7_QueryInterface(IDirectDrawSurface7 *iface, REFIID riid, void **obj) 00134 { 00135 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface7(iface); 00136 00137 TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), obj); 00138 00139 /* According to COM docs, if the QueryInterface fails, obj should be set to NULL */ 00140 *obj = NULL; 00141 00142 if(!riid) 00143 return DDERR_INVALIDPARAMS; 00144 00145 if (IsEqualGUID(riid, &IID_IUnknown) 00146 || IsEqualGUID(riid, &IID_IDirectDrawSurface7) ) 00147 { 00148 IDirectDrawSurface7_AddRef(iface); 00149 *obj = iface; 00150 TRACE("(%p) returning IDirectDrawSurface7 interface at %p\n", This, *obj); 00151 return S_OK; 00152 } 00153 else if (IsEqualGUID(riid, &IID_IDirectDrawSurface4)) 00154 { 00155 IDirectDrawSurface4_AddRef(&This->IDirectDrawSurface4_iface); 00156 *obj = &This->IDirectDrawSurface4_iface; 00157 TRACE("(%p) returning IDirectDrawSurface4 interface at %p\n", This, *obj); 00158 return S_OK; 00159 } 00160 else if (IsEqualGUID(riid, &IID_IDirectDrawSurface3)) 00161 { 00162 IDirectDrawSurface3_AddRef(&This->IDirectDrawSurface3_iface); 00163 *obj = &This->IDirectDrawSurface3_iface; 00164 TRACE("(%p) returning IDirectDrawSurface3 interface at %p\n", This, *obj); 00165 return S_OK; 00166 } 00167 else if (IsEqualGUID(riid, &IID_IDirectDrawSurface2)) 00168 { 00169 IDirectDrawSurface2_AddRef(&This->IDirectDrawSurface2_iface); 00170 *obj = &This->IDirectDrawSurface2_iface; 00171 TRACE("(%p) returning IDirectDrawSurface2 interface at %p\n", This, *obj); 00172 return S_OK; 00173 } 00174 else if (IsEqualGUID(riid, &IID_IDirectDrawSurface)) 00175 { 00176 IDirectDrawSurface_AddRef(&This->IDirectDrawSurface_iface); 00177 *obj = &This->IDirectDrawSurface_iface; 00178 TRACE("(%p) returning IDirectDrawSurface interface at %p\n", This, *obj); 00179 return S_OK; 00180 } 00181 else if( IsEqualGUID(riid, &IID_IDirectDrawGammaControl) ) 00182 { 00183 IDirectDrawGammaControl_AddRef(&This->IDirectDrawGammaControl_iface); 00184 *obj = &This->IDirectDrawGammaControl_iface; 00185 TRACE("(%p) returning IDirectDrawGammaControl interface at %p\n", This, *obj); 00186 return S_OK; 00187 } 00188 else if( IsEqualGUID(riid, &IID_D3DDEVICE_WineD3D) || 00189 IsEqualGUID(riid, &IID_IDirect3DHALDevice)|| 00190 IsEqualGUID(riid, &IID_IDirect3DRGBDevice) ) 00191 { 00192 IDirect3DDevice7 *d3d; 00193 IDirect3DDeviceImpl *device_impl; 00194 00195 /* Call into IDirect3D7 for creation */ 00196 IDirect3D7_CreateDevice(&This->ddraw->IDirect3D7_iface, riid, &This->IDirectDrawSurface7_iface, 00197 &d3d); 00198 00199 if (d3d) 00200 { 00201 device_impl = impl_from_IDirect3DDevice7(d3d); 00202 device_impl->from_surface = TRUE; 00203 *obj = &device_impl->IDirect3DDevice_iface; 00204 TRACE("(%p) Returning IDirect3DDevice interface at %p\n", This, *obj); 00205 return S_OK; 00206 } 00207 00208 WARN("Unable to create a IDirect3DDevice instance, returning E_NOINTERFACE\n"); 00209 return E_NOINTERFACE; 00210 } 00211 else if (IsEqualGUID( &IID_IDirect3DTexture, riid ) || 00212 IsEqualGUID( &IID_IDirect3DTexture2, riid )) 00213 { 00214 if (IsEqualGUID( &IID_IDirect3DTexture, riid )) 00215 { 00216 *obj = &This->IDirect3DTexture_iface; 00217 TRACE(" returning Direct3DTexture interface at %p.\n", *obj); 00218 } 00219 else 00220 { 00221 *obj = &This->IDirect3DTexture2_iface; 00222 TRACE(" returning Direct3DTexture2 interface at %p.\n", *obj); 00223 } 00224 IUnknown_AddRef( (IUnknown *) *obj); 00225 return S_OK; 00226 } 00227 00228 ERR("No interface\n"); 00229 return E_NOINTERFACE; 00230 } 00231 00232 static HRESULT WINAPI ddraw_surface4_QueryInterface(IDirectDrawSurface4 *iface, REFIID riid, void **object) 00233 { 00234 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface4(iface); 00235 TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object); 00236 00237 return ddraw_surface7_QueryInterface(&This->IDirectDrawSurface7_iface, riid, object); 00238 } 00239 00240 static HRESULT WINAPI ddraw_surface3_QueryInterface(IDirectDrawSurface3 *iface, REFIID riid, void **object) 00241 { 00242 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface3(iface); 00243 TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object); 00244 00245 return ddraw_surface7_QueryInterface(&This->IDirectDrawSurface7_iface, riid, object); 00246 } 00247 00248 static HRESULT WINAPI ddraw_surface2_QueryInterface(IDirectDrawSurface2 *iface, REFIID riid, void **object) 00249 { 00250 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface2(iface); 00251 TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object); 00252 00253 return ddraw_surface7_QueryInterface(&This->IDirectDrawSurface7_iface, riid, object); 00254 } 00255 00256 static HRESULT WINAPI ddraw_surface1_QueryInterface(IDirectDrawSurface *iface, REFIID riid, void **object) 00257 { 00258 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface(iface); 00259 TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object); 00260 00261 return ddraw_surface7_QueryInterface(&This->IDirectDrawSurface7_iface, riid, object); 00262 } 00263 00264 static HRESULT WINAPI ddraw_gamma_control_QueryInterface(IDirectDrawGammaControl *iface, 00265 REFIID riid, void **object) 00266 { 00267 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawGammaControl(iface); 00268 00269 TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object); 00270 00271 return ddraw_surface7_QueryInterface(&This->IDirectDrawSurface7_iface, riid, object); 00272 } 00273 00274 static HRESULT WINAPI d3d_texture2_QueryInterface(IDirect3DTexture2 *iface, REFIID riid, void **object) 00275 { 00276 IDirectDrawSurfaceImpl *This = impl_from_IDirect3DTexture2(iface); 00277 TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object); 00278 00279 return ddraw_surface7_QueryInterface(&This->IDirectDrawSurface7_iface, riid, object); 00280 } 00281 00282 static HRESULT WINAPI d3d_texture1_QueryInterface(IDirect3DTexture *iface, REFIID riid, void **object) 00283 { 00284 IDirectDrawSurfaceImpl *This = impl_from_IDirect3DTexture(iface); 00285 TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object); 00286 00287 return ddraw_surface7_QueryInterface(&This->IDirectDrawSurface7_iface, riid, object); 00288 } 00289 00290 static void ddraw_surface_add_iface(IDirectDrawSurfaceImpl *This) 00291 { 00292 ULONG iface_count = InterlockedIncrement(&This->iface_count); 00293 TRACE("%p increasing iface count to %u.\n", This, iface_count); 00294 00295 if (iface_count == 1) 00296 { 00297 wined3d_mutex_lock(); 00298 if (This->wined3d_surface) 00299 wined3d_surface_incref(This->wined3d_surface); 00300 if (This->wined3d_texture) 00301 wined3d_texture_incref(This->wined3d_texture); 00302 wined3d_mutex_unlock(); 00303 } 00304 } 00305 00306 /***************************************************************************** 00307 * IDirectDrawSurface7::AddRef 00308 * 00309 * A normal addref implementation 00310 * 00311 * Returns: 00312 * The new refcount 00313 * 00314 *****************************************************************************/ 00315 static ULONG WINAPI ddraw_surface7_AddRef(IDirectDrawSurface7 *iface) 00316 { 00317 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface7(iface); 00318 ULONG refcount = InterlockedIncrement(&This->ref7); 00319 00320 TRACE("iface %p increasing refcount to %u.\n", iface, refcount); 00321 00322 if (refcount == 1) 00323 { 00324 ddraw_surface_add_iface(This); 00325 } 00326 00327 return refcount; 00328 } 00329 00330 static ULONG WINAPI ddraw_surface4_AddRef(IDirectDrawSurface4 *iface) 00331 { 00332 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface4(iface); 00333 ULONG refcount = InterlockedIncrement(&This->ref4); 00334 00335 TRACE("iface %p increasing refcount to %u.\n", iface, refcount); 00336 00337 if (refcount == 1) 00338 { 00339 ddraw_surface_add_iface(This); 00340 } 00341 00342 return refcount; 00343 } 00344 00345 static ULONG WINAPI ddraw_surface3_AddRef(IDirectDrawSurface3 *iface) 00346 { 00347 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface3(iface); 00348 ULONG refcount = InterlockedIncrement(&This->ref3); 00349 00350 TRACE("iface %p increasing refcount to %u.\n", iface, refcount); 00351 00352 if (refcount == 1) 00353 { 00354 ddraw_surface_add_iface(This); 00355 } 00356 00357 return refcount; 00358 } 00359 00360 static ULONG WINAPI ddraw_surface2_AddRef(IDirectDrawSurface2 *iface) 00361 { 00362 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface2(iface); 00363 ULONG refcount = InterlockedIncrement(&This->ref2); 00364 00365 TRACE("iface %p increasing refcount to %u.\n", iface, refcount); 00366 00367 if (refcount == 1) 00368 { 00369 ddraw_surface_add_iface(This); 00370 } 00371 00372 return refcount; 00373 } 00374 00375 static ULONG WINAPI ddraw_surface1_AddRef(IDirectDrawSurface *iface) 00376 { 00377 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface(iface); 00378 ULONG refcount = InterlockedIncrement(&This->ref1); 00379 00380 TRACE("iface %p increasing refcount to %u.\n", iface, refcount); 00381 00382 if (refcount == 1) 00383 { 00384 ddraw_surface_add_iface(This); 00385 } 00386 00387 return refcount; 00388 } 00389 00390 static ULONG WINAPI ddraw_gamma_control_AddRef(IDirectDrawGammaControl *iface) 00391 { 00392 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawGammaControl(iface); 00393 ULONG refcount = InterlockedIncrement(&This->gamma_count); 00394 00395 TRACE("iface %p increasing refcount to %u.\n", iface, refcount); 00396 00397 if (refcount == 1) 00398 { 00399 ddraw_surface_add_iface(This); 00400 } 00401 00402 return refcount; 00403 } 00404 00405 static ULONG WINAPI d3d_texture2_AddRef(IDirect3DTexture2 *iface) 00406 { 00407 IDirectDrawSurfaceImpl *This = impl_from_IDirect3DTexture2(iface); 00408 TRACE("iface %p.\n", iface); 00409 00410 return ddraw_surface1_AddRef(&This->IDirectDrawSurface_iface); 00411 } 00412 00413 static ULONG WINAPI d3d_texture1_AddRef(IDirect3DTexture *iface) 00414 { 00415 IDirectDrawSurfaceImpl *This = impl_from_IDirect3DTexture(iface); 00416 TRACE("iface %p.\n", iface); 00417 00418 return ddraw_surface1_AddRef(&This->IDirectDrawSurface_iface); 00419 } 00420 00421 /***************************************************************************** 00422 * ddraw_surface_destroy 00423 * 00424 * A helper function for IDirectDrawSurface7::Release 00425 * 00426 * Frees the surface, regardless of its refcount. 00427 * See IDirectDrawSurface7::Release for more information 00428 * 00429 * Params: 00430 * This: Surface to free 00431 * 00432 *****************************************************************************/ 00433 static void ddraw_surface_destroy(IDirectDrawSurfaceImpl *This) 00434 { 00435 TRACE("surface %p.\n", This); 00436 00437 /* Check the iface count and give a warning */ 00438 if(This->iface_count > 1) 00439 { 00440 /* This can happen when a complex surface is destroyed, 00441 * because the 2nd surface was addref()ed when the app 00442 * called GetAttachedSurface 00443 */ 00444 WARN("(%p): Destroying surface with refcounts 7: %d 4: %d 3: %d 2: %d 1: %d\n", 00445 This, This->ref7, This->ref4, This->ref3, This->ref2, This->ref1); 00446 } 00447 00448 if (This->wined3d_surface) 00449 wined3d_surface_decref(This->wined3d_surface); 00450 } 00451 00452 static void ddraw_surface_cleanup(IDirectDrawSurfaceImpl *surface) 00453 { 00454 IDirectDrawSurfaceImpl *surf; 00455 IUnknown *ifaceToRelease; 00456 UINT i; 00457 00458 TRACE("surface %p.\n", surface); 00459 00460 /* The refcount test shows that the palette is detached when the surface 00461 * is destroyed. */ 00462 IDirectDrawSurface7_SetPalette(&surface->IDirectDrawSurface7_iface, NULL); 00463 00464 /* Loop through all complex attached surfaces and destroy them. 00465 * 00466 * Yet again, only the root can have more than one complexly attached 00467 * surface, all the others have a total of one. */ 00468 for (i = 0; i < MAX_COMPLEX_ATTACHED; ++i) 00469 { 00470 if (!surface->complex_array[i]) 00471 break; 00472 00473 surf = surface->complex_array[i]; 00474 surface->complex_array[i] = NULL; 00475 while (surf) 00476 { 00477 IDirectDrawSurfaceImpl *destroy = surf; 00478 surf = surf->complex_array[0]; /* Iterate through the "tree" */ 00479 ddraw_surface_destroy(destroy); /* Destroy it */ 00480 } 00481 } 00482 00483 ifaceToRelease = surface->ifaceToRelease; 00484 00485 /* Destroy the root surface. */ 00486 ddraw_surface_destroy(surface); 00487 00488 /* Reduce the ddraw refcount */ 00489 if (ifaceToRelease) 00490 IUnknown_Release(ifaceToRelease); 00491 } 00492 00493 ULONG ddraw_surface_release_iface(IDirectDrawSurfaceImpl *This) 00494 { 00495 ULONG iface_count = InterlockedDecrement(&This->iface_count); 00496 TRACE("%p decreasing iface count to %u.\n", This, iface_count); 00497 00498 if (iface_count == 0) 00499 { 00500 /* Complex attached surfaces are destroyed implicitly when the root is released */ 00501 wined3d_mutex_lock(); 00502 if(!This->is_complex_root) 00503 { 00504 WARN("(%p) Attempt to destroy a surface that is not a complex root\n", This); 00505 wined3d_mutex_unlock(); 00506 return iface_count; 00507 } 00508 if (This->wined3d_texture) /* If it's a texture, destroy the wined3d texture. */ 00509 wined3d_texture_decref(This->wined3d_texture); 00510 else 00511 ddraw_surface_cleanup(This); 00512 wined3d_mutex_unlock(); 00513 } 00514 00515 return iface_count; 00516 } 00517 00518 /***************************************************************************** 00519 * IDirectDrawSurface7::Release 00520 * 00521 * Reduces the surface's refcount by 1. If the refcount falls to 0, the 00522 * surface is destroyed. 00523 * 00524 * Destroying the surface is a bit tricky. For the connection between 00525 * WineD3DSurfaces and DirectDrawSurfaces see IDirectDraw7::CreateSurface 00526 * It has a nice graph explaining the connection. 00527 * 00528 * What happens here is basically this: 00529 * When a surface is destroyed, its WineD3DSurface is released, 00530 * and the refcount of the DirectDraw interface is reduced by 1. If it has 00531 * complex surfaces attached to it, then these surfaces are destroyed too, 00532 * regardless of their refcount. If any surface being destroyed has another 00533 * surface attached to it (with a "soft" attachment, not complex), then 00534 * this surface is detached with DeleteAttachedSurface. 00535 * 00536 * When the surface is a texture, the WineD3DTexture is released. 00537 * If the surface is the Direct3D render target, then the D3D 00538 * capabilities of the WineD3DDevice are uninitialized, which causes the 00539 * swapchain to be released. 00540 * 00541 * When a complex sublevel falls to ref zero, then this is ignored. 00542 * 00543 * Returns: 00544 * The new refcount 00545 * 00546 *****************************************************************************/ 00547 static ULONG WINAPI ddraw_surface7_Release(IDirectDrawSurface7 *iface) 00548 { 00549 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface7(iface); 00550 ULONG refcount = InterlockedDecrement(&This->ref7); 00551 00552 TRACE("iface %p decreasing refcount to %u.\n", iface, refcount); 00553 00554 if (refcount == 0) 00555 { 00556 ddraw_surface_release_iface(This); 00557 } 00558 00559 return refcount; 00560 } 00561 00562 static ULONG WINAPI ddraw_surface4_Release(IDirectDrawSurface4 *iface) 00563 { 00564 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface4(iface); 00565 ULONG refcount = InterlockedDecrement(&This->ref4); 00566 00567 TRACE("iface %p decreasing refcount to %u.\n", iface, refcount); 00568 00569 if (refcount == 0) 00570 { 00571 ddraw_surface_release_iface(This); 00572 } 00573 00574 return refcount; 00575 } 00576 00577 static ULONG WINAPI ddraw_surface3_Release(IDirectDrawSurface3 *iface) 00578 { 00579 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface3(iface); 00580 ULONG refcount = InterlockedDecrement(&This->ref3); 00581 00582 TRACE("iface %p decreasing refcount to %u.\n", iface, refcount); 00583 00584 if (refcount == 0) 00585 { 00586 ddraw_surface_release_iface(This); 00587 } 00588 00589 return refcount; 00590 } 00591 00592 static ULONG WINAPI ddraw_surface2_Release(IDirectDrawSurface2 *iface) 00593 { 00594 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface2(iface); 00595 ULONG refcount = InterlockedDecrement(&This->ref2); 00596 00597 TRACE("iface %p decreasing refcount to %u.\n", iface, refcount); 00598 00599 if (refcount == 0) 00600 { 00601 ddraw_surface_release_iface(This); 00602 } 00603 00604 return refcount; 00605 } 00606 00607 static ULONG WINAPI ddraw_surface1_Release(IDirectDrawSurface *iface) 00608 { 00609 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface(iface); 00610 ULONG refcount = InterlockedDecrement(&This->ref1); 00611 00612 TRACE("iface %p decreasing refcount to %u.\n", iface, refcount); 00613 00614 if (refcount == 0) 00615 { 00616 ddraw_surface_release_iface(This); 00617 } 00618 00619 return refcount; 00620 } 00621 00622 static ULONG WINAPI ddraw_gamma_control_Release(IDirectDrawGammaControl *iface) 00623 { 00624 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawGammaControl(iface); 00625 ULONG refcount = InterlockedDecrement(&This->gamma_count); 00626 00627 TRACE("iface %p decreasing refcount to %u.\n", iface, refcount); 00628 00629 if (refcount == 0) 00630 { 00631 ddraw_surface_release_iface(This); 00632 } 00633 00634 return refcount; 00635 } 00636 00637 static ULONG WINAPI d3d_texture2_Release(IDirect3DTexture2 *iface) 00638 { 00639 IDirectDrawSurfaceImpl *This = impl_from_IDirect3DTexture2(iface); 00640 TRACE("iface %p.\n", iface); 00641 00642 return ddraw_surface1_Release(&This->IDirectDrawSurface_iface); 00643 } 00644 00645 static ULONG WINAPI d3d_texture1_Release(IDirect3DTexture *iface) 00646 { 00647 IDirectDrawSurfaceImpl *This = impl_from_IDirect3DTexture(iface); 00648 TRACE("iface %p.\n", iface); 00649 00650 return ddraw_surface1_Release(&This->IDirectDrawSurface_iface); 00651 } 00652 00653 /***************************************************************************** 00654 * IDirectDrawSurface7::GetAttachedSurface 00655 * 00656 * Returns an attached surface with the requested caps. Surface attachment 00657 * and complex surfaces are not clearly described by the MSDN or sdk, 00658 * so this method is tricky and likely to contain problems. 00659 * This implementation searches the complex list first, then the 00660 * attachment chain. 00661 * 00662 * The chains are searched from This down to the last surface in the chain, 00663 * not from the first element in the chain. The first surface found is 00664 * returned. The MSDN says that this method fails if more than one surface 00665 * matches the caps, but it is not sure if that is right. The attachment 00666 * structure may not even allow two matching surfaces. 00667 * 00668 * The found surface is AddRef-ed before it is returned. 00669 * 00670 * Params: 00671 * Caps: Pointer to a DDCAPS2 structure describing the caps asked for 00672 * Surface: Address to store the found surface 00673 * 00674 * Returns: 00675 * DD_OK on success 00676 * DDERR_INVALIDPARAMS if Caps or Surface is NULL 00677 * DDERR_NOTFOUND if no surface was found 00678 * 00679 *****************************************************************************/ 00680 static HRESULT WINAPI ddraw_surface7_GetAttachedSurface(IDirectDrawSurface7 *iface, 00681 DDSCAPS2 *Caps, IDirectDrawSurface7 **Surface) 00682 { 00683 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface7(iface); 00684 IDirectDrawSurfaceImpl *surf; 00685 DDSCAPS2 our_caps; 00686 int i; 00687 00688 TRACE("iface %p, caps %p, attachment %p.\n", iface, Caps, Surface); 00689 00690 wined3d_mutex_lock(); 00691 00692 if(This->version < 7) 00693 { 00694 /* Earlier dx apps put garbage into these members, clear them */ 00695 our_caps.dwCaps = Caps->dwCaps; 00696 our_caps.dwCaps2 = 0; 00697 our_caps.dwCaps3 = 0; 00698 our_caps.u1.dwCaps4 = 0; 00699 } 00700 else 00701 { 00702 our_caps = *Caps; 00703 } 00704 00705 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 */ 00706 00707 for(i = 0; i < MAX_COMPLEX_ATTACHED; i++) 00708 { 00709 surf = This->complex_array[i]; 00710 if(!surf) break; 00711 00712 if (TRACE_ON(ddraw)) 00713 { 00714 TRACE("Surface: (%p) caps: %x,%x,%x,%x\n", surf, 00715 surf->surface_desc.ddsCaps.dwCaps, 00716 surf->surface_desc.ddsCaps.dwCaps2, 00717 surf->surface_desc.ddsCaps.dwCaps3, 00718 surf->surface_desc.ddsCaps.u1.dwCaps4); 00719 } 00720 00721 if (((surf->surface_desc.ddsCaps.dwCaps & our_caps.dwCaps) == our_caps.dwCaps) && 00722 ((surf->surface_desc.ddsCaps.dwCaps2 & our_caps.dwCaps2) == our_caps.dwCaps2)) { 00723 00724 /* MSDN: "This method fails if more than one surface is attached 00725 * that matches the capabilities requested." 00726 * 00727 * Not sure how to test this. 00728 */ 00729 00730 TRACE("(%p): Returning surface %p\n", This, surf); 00731 TRACE("(%p): mipmapcount=%d\n", This, surf->mipmap_level); 00732 *Surface = &surf->IDirectDrawSurface7_iface; 00733 ddraw_surface7_AddRef(*Surface); 00734 wined3d_mutex_unlock(); 00735 00736 return DD_OK; 00737 } 00738 } 00739 00740 /* Next, look at the attachment chain */ 00741 surf = This; 00742 00743 while( (surf = surf->next_attached) ) 00744 { 00745 if (TRACE_ON(ddraw)) 00746 { 00747 TRACE("Surface: (%p) caps: %x,%x,%x,%x\n", surf, 00748 surf->surface_desc.ddsCaps.dwCaps, 00749 surf->surface_desc.ddsCaps.dwCaps2, 00750 surf->surface_desc.ddsCaps.dwCaps3, 00751 surf->surface_desc.ddsCaps.u1.dwCaps4); 00752 } 00753 00754 if (((surf->surface_desc.ddsCaps.dwCaps & our_caps.dwCaps) == our_caps.dwCaps) && 00755 ((surf->surface_desc.ddsCaps.dwCaps2 & our_caps.dwCaps2) == our_caps.dwCaps2)) { 00756 00757 TRACE("(%p): Returning surface %p\n", This, surf); 00758 *Surface = &surf->IDirectDrawSurface7_iface; 00759 ddraw_surface7_AddRef(*Surface); 00760 wined3d_mutex_unlock(); 00761 return DD_OK; 00762 } 00763 } 00764 00765 TRACE("(%p) Didn't find a valid surface\n", This); 00766 00767 wined3d_mutex_unlock(); 00768 00769 *Surface = NULL; 00770 return DDERR_NOTFOUND; 00771 } 00772 00773 static HRESULT WINAPI ddraw_surface4_GetAttachedSurface(IDirectDrawSurface4 *iface, 00774 DDSCAPS2 *caps, IDirectDrawSurface4 **attachment) 00775 { 00776 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface4(iface); 00777 IDirectDrawSurface7 *attachment7; 00778 IDirectDrawSurfaceImpl *attachment_impl; 00779 HRESULT hr; 00780 00781 TRACE("iface %p, caps %p, attachment %p.\n", iface, caps, attachment); 00782 00783 hr = ddraw_surface7_GetAttachedSurface(&This->IDirectDrawSurface7_iface, 00784 caps, &attachment7); 00785 if (FAILED(hr)) 00786 { 00787 *attachment = NULL; 00788 return hr; 00789 } 00790 attachment_impl = impl_from_IDirectDrawSurface7(attachment7); 00791 *attachment = &attachment_impl->IDirectDrawSurface4_iface; 00792 ddraw_surface4_AddRef(*attachment); 00793 ddraw_surface7_Release(attachment7); 00794 00795 return hr; 00796 } 00797 00798 static HRESULT WINAPI ddraw_surface3_GetAttachedSurface(IDirectDrawSurface3 *iface, 00799 DDSCAPS *caps, IDirectDrawSurface3 **attachment) 00800 { 00801 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface3(iface); 00802 IDirectDrawSurface7 *attachment7; 00803 IDirectDrawSurfaceImpl *attachment_impl; 00804 DDSCAPS2 caps2; 00805 HRESULT hr; 00806 00807 TRACE("iface %p, caps %p, attachment %p.\n", iface, caps, attachment); 00808 00809 caps2.dwCaps = caps->dwCaps; 00810 caps2.dwCaps2 = 0; 00811 caps2.dwCaps3 = 0; 00812 caps2.u1.dwCaps4 = 0; 00813 00814 hr = ddraw_surface7_GetAttachedSurface(&This->IDirectDrawSurface7_iface, 00815 &caps2, &attachment7); 00816 if (FAILED(hr)) 00817 { 00818 *attachment = NULL; 00819 return hr; 00820 } 00821 attachment_impl = impl_from_IDirectDrawSurface7(attachment7); 00822 *attachment = &attachment_impl->IDirectDrawSurface3_iface; 00823 ddraw_surface3_AddRef(*attachment); 00824 ddraw_surface7_Release(attachment7); 00825 00826 return hr; 00827 } 00828 00829 static HRESULT WINAPI ddraw_surface2_GetAttachedSurface(IDirectDrawSurface2 *iface, 00830 DDSCAPS *caps, IDirectDrawSurface2 **attachment) 00831 { 00832 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface2(iface); 00833 IDirectDrawSurface7 *attachment7; 00834 IDirectDrawSurfaceImpl *attachment_impl; 00835 DDSCAPS2 caps2; 00836 HRESULT hr; 00837 00838 TRACE("iface %p, caps %p, attachment %p.\n", iface, caps, attachment); 00839 00840 caps2.dwCaps = caps->dwCaps; 00841 caps2.dwCaps2 = 0; 00842 caps2.dwCaps3 = 0; 00843 caps2.u1.dwCaps4 = 0; 00844 00845 hr = ddraw_surface7_GetAttachedSurface(&This->IDirectDrawSurface7_iface, 00846 &caps2, &attachment7); 00847 if (FAILED(hr)) 00848 { 00849 *attachment = NULL; 00850 return hr; 00851 } 00852 attachment_impl = impl_from_IDirectDrawSurface7(attachment7); 00853 *attachment = &attachment_impl->IDirectDrawSurface2_iface; 00854 ddraw_surface2_AddRef(*attachment); 00855 ddraw_surface7_Release(attachment7); 00856 00857 return hr; 00858 } 00859 00860 static HRESULT WINAPI ddraw_surface1_GetAttachedSurface(IDirectDrawSurface *iface, 00861 DDSCAPS *caps, IDirectDrawSurface **attachment) 00862 { 00863 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface(iface); 00864 IDirectDrawSurface7 *attachment7; 00865 IDirectDrawSurfaceImpl *attachment_impl; 00866 DDSCAPS2 caps2; 00867 HRESULT hr; 00868 00869 TRACE("iface %p, caps %p, attachment %p.\n", iface, caps, attachment); 00870 00871 caps2.dwCaps = caps->dwCaps; 00872 caps2.dwCaps2 = 0; 00873 caps2.dwCaps3 = 0; 00874 caps2.u1.dwCaps4 = 0; 00875 00876 hr = ddraw_surface7_GetAttachedSurface(&This->IDirectDrawSurface7_iface, 00877 &caps2, &attachment7); 00878 if (FAILED(hr)) 00879 { 00880 *attachment = NULL; 00881 return hr; 00882 } 00883 attachment_impl = impl_from_IDirectDrawSurface7(attachment7); 00884 *attachment = &attachment_impl->IDirectDrawSurface_iface; 00885 ddraw_surface1_AddRef(*attachment); 00886 ddraw_surface7_Release(attachment7); 00887 00888 return hr; 00889 } 00890 00891 /***************************************************************************** 00892 * IDirectDrawSurface7::Lock 00893 * 00894 * Locks the surface and returns a pointer to the surface's memory 00895 * 00896 * Params: 00897 * Rect: Rectangle to lock. If NULL, the whole surface is locked 00898 * DDSD: Pointer to a DDSURFACEDESC2 which shall receive the surface's desc. 00899 * Flags: Locking flags, e.g Read only or write only 00900 * h: An event handle that's not used and must be NULL 00901 * 00902 * Returns: 00903 * DD_OK on success 00904 * DDERR_INVALIDPARAMS if DDSD is NULL 00905 * For more details, see IWineD3DSurface::LockRect 00906 * 00907 *****************************************************************************/ 00908 static HRESULT surface_lock(IDirectDrawSurfaceImpl *This, 00909 RECT *Rect, DDSURFACEDESC2 *DDSD, DWORD Flags, HANDLE h) 00910 { 00911 struct wined3d_mapped_rect mapped_rect; 00912 HRESULT hr = DD_OK; 00913 00914 TRACE("This %p, rect %s, surface_desc %p, flags %#x, h %p.\n", 00915 This, wine_dbgstr_rect(Rect), DDSD, Flags, h); 00916 00917 /* This->surface_desc.dwWidth and dwHeight are changeable, thus lock */ 00918 wined3d_mutex_lock(); 00919 00920 /* Should I check for the handle to be NULL? 00921 * 00922 * The DDLOCK flags and the D3DLOCK flags are equal 00923 * for the supported values. The others are ignored by WineD3D 00924 */ 00925 00926 /* Windows zeroes this if the rect is invalid */ 00927 DDSD->lpSurface = 0; 00928 00929 if (Rect) 00930 { 00931 if ((Rect->left < 0) 00932 || (Rect->top < 0) 00933 || (Rect->left > Rect->right) 00934 || (Rect->top > Rect->bottom) 00935 || (Rect->right > This->surface_desc.dwWidth) 00936 || (Rect->bottom > This->surface_desc.dwHeight)) 00937 { 00938 WARN("Trying to lock an invalid rectangle, returning DDERR_INVALIDPARAMS\n"); 00939 wined3d_mutex_unlock(); 00940 return DDERR_INVALIDPARAMS; 00941 } 00942 } 00943 00944 if (This->surface_desc.ddsCaps.dwCaps & DDSCAPS_FRONTBUFFER) 00945 hr = ddraw_surface_update_frontbuffer(This, Rect, TRUE); 00946 if (SUCCEEDED(hr)) 00947 hr = wined3d_surface_map(This->wined3d_surface, &mapped_rect, Rect, Flags); 00948 if (FAILED(hr)) 00949 { 00950 wined3d_mutex_unlock(); 00951 switch(hr) 00952 { 00953 /* D3D8 and D3D9 return the general D3DERR_INVALIDCALL error, but ddraw has a more 00954 * specific error. But since IWineD3DSurface::LockRect returns that error in this 00955 * only occasion, keep d3d8 and d3d9 free from the return value override. There are 00956 * many different places where d3d8/9 would have to catch the DDERR_SURFACEBUSY, it 00957 * is much easier to do it in one place in ddraw 00958 */ 00959 case WINED3DERR_INVALIDCALL: return DDERR_SURFACEBUSY; 00960 default: return hr; 00961 } 00962 } 00963 00964 if (This->surface_desc.ddsCaps.dwCaps & DDSCAPS_FRONTBUFFER) 00965 { 00966 if (Flags & DDLOCK_READONLY) 00967 memset(&This->ddraw->primary_lock, 0, sizeof(This->ddraw->primary_lock)); 00968 else if (Rect) 00969 This->ddraw->primary_lock = *Rect; 00970 else 00971 SetRect(&This->ddraw->primary_lock, 0, 0, This->surface_desc.dwWidth, This->surface_desc.dwHeight); 00972 } 00973 00974 /* Override the memory area. The pitch should be set already. Strangely windows 00975 * does not set the LPSURFACE flag on locked surfaces !?!. 00976 * DDSD->dwFlags |= DDSD_LPSURFACE; 00977 */ 00978 This->surface_desc.lpSurface = mapped_rect.data; 00979 DD_STRUCT_COPY_BYSIZE(DDSD,&(This->surface_desc)); 00980 00981 TRACE("locked surface returning description :\n"); 00982 if (TRACE_ON(ddraw)) DDRAW_dump_surface_desc(DDSD); 00983 00984 wined3d_mutex_unlock(); 00985 00986 return DD_OK; 00987 } 00988 00989 static HRESULT WINAPI ddraw_surface7_Lock(IDirectDrawSurface7 *iface, 00990 RECT *rect, DDSURFACEDESC2 *surface_desc, DWORD flags, HANDLE h) 00991 { 00992 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface7(iface); 00993 TRACE("iface %p, rect %s, surface_desc %p, flags %#x, h %p.\n", 00994 iface, wine_dbgstr_rect(rect), surface_desc, flags, h); 00995 00996 if (!surface_desc) return DDERR_INVALIDPARAMS; 00997 if (surface_desc->dwSize != sizeof(DDSURFACEDESC) && 00998 surface_desc->dwSize != sizeof(DDSURFACEDESC2)) 00999 { 01000 WARN("Invalid structure size %d, returning DDERR_INVALIDPARAMS\n", surface_desc->dwSize); 01001 return DDERR_INVALIDPARAMS; 01002 } 01003 return surface_lock(This, rect, surface_desc, flags, h); 01004 } 01005 01006 static HRESULT WINAPI ddraw_surface4_Lock(IDirectDrawSurface4 *iface, RECT *rect, 01007 DDSURFACEDESC2 *surface_desc, DWORD flags, HANDLE h) 01008 { 01009 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface4(iface); 01010 TRACE("iface %p, rect %s, surface_desc %p, flags %#x, h %p.\n", 01011 iface, wine_dbgstr_rect(rect), surface_desc, flags, h); 01012 01013 if (!surface_desc) return DDERR_INVALIDPARAMS; 01014 if (surface_desc->dwSize != sizeof(DDSURFACEDESC) && 01015 surface_desc->dwSize != sizeof(DDSURFACEDESC2)) 01016 { 01017 WARN("Invalid structure size %d, returning DDERR_INVALIDPARAMS\n", surface_desc->dwSize); 01018 return DDERR_INVALIDPARAMS; 01019 } 01020 return surface_lock(This, rect, surface_desc, flags, h); 01021 } 01022 01023 static HRESULT WINAPI ddraw_surface3_Lock(IDirectDrawSurface3 *iface, RECT *rect, 01024 DDSURFACEDESC *surface_desc, DWORD flags, HANDLE h) 01025 { 01026 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface3(iface); 01027 DDSURFACEDESC2 surface_desc2; 01028 HRESULT hr; 01029 TRACE("iface %p, rect %s, surface_desc %p, flags %#x, h %p.\n", 01030 iface, wine_dbgstr_rect(rect), surface_desc, flags, h); 01031 01032 if (!surface_desc) return DDERR_INVALIDPARAMS; 01033 if (surface_desc->dwSize != sizeof(DDSURFACEDESC) && 01034 surface_desc->dwSize != sizeof(DDSURFACEDESC2)) 01035 { 01036 WARN("Invalid structure size %d, returning DDERR_INVALIDPARAMS\n", surface_desc->dwSize); 01037 return DDERR_INVALIDPARAMS; 01038 } 01039 01040 surface_desc2.dwSize = surface_desc->dwSize; 01041 surface_desc2.dwFlags = 0; 01042 hr = surface_lock(This, rect, &surface_desc2, flags, h); 01043 DDSD2_to_DDSD(&surface_desc2, surface_desc); 01044 surface_desc->dwSize = surface_desc2.dwSize; 01045 return hr; 01046 } 01047 01048 static HRESULT WINAPI ddraw_surface2_Lock(IDirectDrawSurface2 *iface, RECT *rect, 01049 DDSURFACEDESC *surface_desc, DWORD flags, HANDLE h) 01050 { 01051 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface2(iface); 01052 DDSURFACEDESC2 surface_desc2; 01053 HRESULT hr; 01054 TRACE("iface %p, rect %s, surface_desc %p, flags %#x, h %p.\n", 01055 iface, wine_dbgstr_rect(rect), surface_desc, flags, h); 01056 01057 if (!surface_desc) return DDERR_INVALIDPARAMS; 01058 if (surface_desc->dwSize != sizeof(DDSURFACEDESC) && 01059 surface_desc->dwSize != sizeof(DDSURFACEDESC2)) 01060 { 01061 WARN("Invalid structure size %d, returning DDERR_INVALIDPARAMS\n", surface_desc->dwSize); 01062 return DDERR_INVALIDPARAMS; 01063 } 01064 01065 surface_desc2.dwSize = surface_desc->dwSize; 01066 surface_desc2.dwFlags = 0; 01067 hr = surface_lock(This, rect, &surface_desc2, flags, h); 01068 DDSD2_to_DDSD(&surface_desc2, surface_desc); 01069 surface_desc->dwSize = surface_desc2.dwSize; 01070 return hr; 01071 } 01072 01073 static HRESULT WINAPI ddraw_surface1_Lock(IDirectDrawSurface *iface, RECT *rect, 01074 DDSURFACEDESC *surface_desc, DWORD flags, HANDLE h) 01075 { 01076 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface(iface); 01077 DDSURFACEDESC2 surface_desc2; 01078 HRESULT hr; 01079 TRACE("iface %p, rect %s, surface_desc %p, flags %#x, h %p.\n", 01080 iface, wine_dbgstr_rect(rect), surface_desc, flags, h); 01081 01082 if (!surface_desc) return DDERR_INVALIDPARAMS; 01083 if (surface_desc->dwSize != sizeof(DDSURFACEDESC) && 01084 surface_desc->dwSize != sizeof(DDSURFACEDESC2)) 01085 { 01086 WARN("Invalid structure size %d, returning DDERR_INVALIDPARAMS\n", surface_desc->dwSize); 01087 return DDERR_INVALIDPARAMS; 01088 } 01089 01090 surface_desc2.dwSize = surface_desc->dwSize; 01091 surface_desc2.dwFlags = 0; 01092 hr = surface_lock(This, rect, &surface_desc2, flags, h); 01093 DDSD2_to_DDSD(&surface_desc2, surface_desc); 01094 surface_desc->dwSize = surface_desc2.dwSize; 01095 return hr; 01096 } 01097 01098 /***************************************************************************** 01099 * IDirectDrawSurface7::Unlock 01100 * 01101 * Unlocks an locked surface 01102 * 01103 * Params: 01104 * Rect: Not used by this implementation 01105 * 01106 * Returns: 01107 * D3D_OK on success 01108 * For more details, see IWineD3DSurface::UnlockRect 01109 * 01110 *****************************************************************************/ 01111 static HRESULT WINAPI ddraw_surface7_Unlock(IDirectDrawSurface7 *iface, RECT *pRect) 01112 { 01113 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface7(iface); 01114 HRESULT hr; 01115 01116 TRACE("iface %p, rect %s.\n", iface, wine_dbgstr_rect(pRect)); 01117 01118 wined3d_mutex_lock(); 01119 hr = wined3d_surface_unmap(This->wined3d_surface); 01120 if (SUCCEEDED(hr)) 01121 { 01122 if (This->surface_desc.ddsCaps.dwCaps & DDSCAPS_FRONTBUFFER) 01123 hr = ddraw_surface_update_frontbuffer(This, &This->ddraw->primary_lock, FALSE); 01124 This->surface_desc.lpSurface = NULL; 01125 } 01126 wined3d_mutex_unlock(); 01127 01128 return hr; 01129 } 01130 01131 static HRESULT WINAPI ddraw_surface4_Unlock(IDirectDrawSurface4 *iface, RECT *pRect) 01132 { 01133 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface4(iface); 01134 TRACE("iface %p, rect %p.\n", iface, pRect); 01135 01136 return ddraw_surface7_Unlock(&This->IDirectDrawSurface7_iface, pRect); 01137 } 01138 01139 static HRESULT WINAPI ddraw_surface3_Unlock(IDirectDrawSurface3 *iface, void *data) 01140 { 01141 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface3(iface); 01142 TRACE("iface %p, data %p.\n", iface, data); 01143 01144 /* data might not be the LPRECT of later versions, so drop it. */ 01145 return ddraw_surface7_Unlock(&This->IDirectDrawSurface7_iface, NULL); 01146 } 01147 01148 static HRESULT WINAPI ddraw_surface2_Unlock(IDirectDrawSurface2 *iface, void *data) 01149 { 01150 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface2(iface); 01151 TRACE("iface %p, data %p.\n", iface, data); 01152 01153 /* data might not be the LPRECT of later versions, so drop it. */ 01154 return ddraw_surface7_Unlock(&This->IDirectDrawSurface7_iface, NULL); 01155 } 01156 01157 static HRESULT WINAPI ddraw_surface1_Unlock(IDirectDrawSurface *iface, void *data) 01158 { 01159 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface(iface); 01160 TRACE("iface %p, data %p.\n", iface, data); 01161 01162 /* data might not be the LPRECT of later versions, so drop it. */ 01163 return ddraw_surface7_Unlock(&This->IDirectDrawSurface7_iface, NULL); 01164 } 01165 01166 /***************************************************************************** 01167 * IDirectDrawSurface7::Flip 01168 * 01169 * Flips a surface with the DDSCAPS_FLIP flag. The flip is relayed to 01170 * IWineD3DSurface::Flip. Because WineD3D doesn't handle attached surfaces, 01171 * the flip target is passed to WineD3D, even if the app didn't specify one 01172 * 01173 * Params: 01174 * DestOverride: Specifies the surface that will become the new front 01175 * buffer. If NULL, the current back buffer is used 01176 * Flags: some DirectDraw flags, see include/ddraw.h 01177 * 01178 * Returns: 01179 * DD_OK on success 01180 * DDERR_NOTFLIPPABLE if no flip target could be found 01181 * DDERR_INVALIDOBJECT if the surface isn't a front buffer 01182 * For more details, see IWineD3DSurface::Flip 01183 * 01184 *****************************************************************************/ 01185 static HRESULT WINAPI ddraw_surface7_Flip(IDirectDrawSurface7 *iface, IDirectDrawSurface7 *DestOverride, DWORD Flags) 01186 { 01187 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface7(iface); 01188 IDirectDrawSurfaceImpl *Override = unsafe_impl_from_IDirectDrawSurface7(DestOverride); 01189 IDirectDrawSurface7 *Override7; 01190 HRESULT hr; 01191 01192 TRACE("iface %p, dst %p, flags %#x.\n", iface, DestOverride, Flags); 01193 01194 /* Flip has to be called from a front buffer 01195 * What about overlay surfaces, AFAIK they can flip too? 01196 */ 01197 if( !(This->surface_desc.ddsCaps.dwCaps & (DDSCAPS_FRONTBUFFER | DDSCAPS_OVERLAY)) ) 01198 return DDERR_INVALIDOBJECT; /* Unchecked */ 01199 01200 wined3d_mutex_lock(); 01201 01202 /* WineD3D doesn't keep track of attached surface, so find the target */ 01203 if(!Override) 01204 { 01205 DDSCAPS2 Caps; 01206 01207 memset(&Caps, 0, sizeof(Caps)); 01208 Caps.dwCaps |= DDSCAPS_BACKBUFFER; 01209 hr = ddraw_surface7_GetAttachedSurface(iface, &Caps, &Override7); 01210 if(hr != DD_OK) 01211 { 01212 ERR("Can't find a flip target\n"); 01213 wined3d_mutex_unlock(); 01214 return DDERR_NOTFLIPPABLE; /* Unchecked */ 01215 } 01216 Override = impl_from_IDirectDrawSurface7(Override7); 01217 01218 /* For the GetAttachedSurface */ 01219 ddraw_surface7_Release(Override7); 01220 } 01221 01222 hr = wined3d_surface_flip(This->wined3d_surface, Override->wined3d_surface, Flags); 01223 if (SUCCEEDED(hr) && This->surface_desc.ddsCaps.dwCaps & DDSCAPS_FRONTBUFFER) 01224 hr = ddraw_surface_update_frontbuffer(This, NULL, FALSE); 01225 01226 wined3d_mutex_unlock(); 01227 01228 return hr; 01229 } 01230 01231 static HRESULT WINAPI ddraw_surface4_Flip(IDirectDrawSurface4 *iface, IDirectDrawSurface4 *dst, DWORD flags) 01232 { 01233 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface4(iface); 01234 IDirectDrawSurfaceImpl *dst_impl = unsafe_impl_from_IDirectDrawSurface4(dst); 01235 TRACE("iface %p, dst %p, flags %#x.\n", iface, dst, flags); 01236 01237 return ddraw_surface7_Flip(&This->IDirectDrawSurface7_iface, 01238 dst_impl ? &dst_impl->IDirectDrawSurface7_iface : NULL, flags); 01239 } 01240 01241 static HRESULT WINAPI ddraw_surface3_Flip(IDirectDrawSurface3 *iface, IDirectDrawSurface3 *dst, DWORD flags) 01242 { 01243 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface3(iface); 01244 IDirectDrawSurfaceImpl *dst_impl = unsafe_impl_from_IDirectDrawSurface3(dst); 01245 TRACE("iface %p, dst %p, flags %#x.\n", iface, dst, flags); 01246 01247 return ddraw_surface7_Flip(&This->IDirectDrawSurface7_iface, 01248 dst_impl ? &dst_impl->IDirectDrawSurface7_iface : NULL, flags); 01249 } 01250 01251 static HRESULT WINAPI ddraw_surface2_Flip(IDirectDrawSurface2 *iface, IDirectDrawSurface2 *dst, DWORD flags) 01252 { 01253 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface2(iface); 01254 IDirectDrawSurfaceImpl *dst_impl = unsafe_impl_from_IDirectDrawSurface2(dst); 01255 TRACE("iface %p, dst %p, flags %#x.\n", iface, dst, flags); 01256 01257 return ddraw_surface7_Flip(&This->IDirectDrawSurface7_iface, 01258 dst_impl ? &dst_impl->IDirectDrawSurface7_iface : NULL, flags); 01259 } 01260 01261 static HRESULT WINAPI ddraw_surface1_Flip(IDirectDrawSurface *iface, IDirectDrawSurface *dst, DWORD flags) 01262 { 01263 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface(iface); 01264 IDirectDrawSurfaceImpl *dst_impl = unsafe_impl_from_IDirectDrawSurface(dst); 01265 TRACE("iface %p, dst %p, flags %#x.\n", iface, dst, flags); 01266 01267 return ddraw_surface7_Flip(&This->IDirectDrawSurface7_iface, 01268 dst_impl ? &dst_impl->IDirectDrawSurface7_iface : NULL, flags); 01269 } 01270 01271 static HRESULT ddraw_surface_blt_clipped(IDirectDrawSurfaceImpl *dst_surface, const RECT *dst_rect_in, 01272 IDirectDrawSurfaceImpl *src_surface, const RECT *src_rect_in, DWORD flags, 01273 const WINEDDBLTFX *fx, enum wined3d_texture_filter_type filter) 01274 { 01275 struct wined3d_surface *wined3d_src_surface = src_surface ? src_surface->wined3d_surface : NULL; 01276 RECT src_rect, dst_rect; 01277 float scale_x, scale_y; 01278 const RECT *clip_rect; 01279 UINT clip_list_size; 01280 RGNDATA *clip_list; 01281 HRESULT hr = DD_OK; 01282 UINT i; 01283 01284 if (!dst_surface->clipper) 01285 { 01286 if (src_surface && src_surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_FRONTBUFFER) 01287 hr = ddraw_surface_update_frontbuffer(src_surface, src_rect_in, TRUE); 01288 if (SUCCEEDED(hr)) 01289 hr = wined3d_surface_blt(dst_surface->wined3d_surface, dst_rect_in, 01290 wined3d_src_surface, src_rect_in, flags, fx, filter); 01291 if (SUCCEEDED(hr) && (dst_surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_FRONTBUFFER)) 01292 hr = ddraw_surface_update_frontbuffer(dst_surface, dst_rect_in, FALSE); 01293 01294 return hr; 01295 } 01296 01297 if (!dst_rect_in) 01298 { 01299 dst_rect.left = 0; 01300 dst_rect.top = 0; 01301 dst_rect.right = dst_surface->surface_desc.dwWidth; 01302 dst_rect.bottom = dst_surface->surface_desc.dwHeight; 01303 } 01304 else 01305 { 01306 dst_rect = *dst_rect_in; 01307 } 01308 01309 if (IsRectEmpty(&dst_rect)) 01310 return DDERR_INVALIDRECT; 01311 01312 if (src_surface) 01313 { 01314 if (!src_rect_in) 01315 { 01316 src_rect.left = 0; 01317 src_rect.top = 0; 01318 src_rect.right = src_surface->surface_desc.dwWidth; 01319 src_rect.bottom = src_surface->surface_desc.dwHeight; 01320 } 01321 else 01322 { 01323 src_rect = *src_rect_in; 01324 } 01325 01326 if (IsRectEmpty(&src_rect)) 01327 return DDERR_INVALIDRECT; 01328 } 01329 else 01330 { 01331 SetRect(&src_rect, 0, 0, 0, 0); 01332 } 01333 01334 scale_x = (float)(src_rect.right - src_rect.left) / (float)(dst_rect.right - dst_rect.left); 01335 scale_y = (float)(src_rect.bottom - src_rect.top) / (float)(dst_rect.bottom - dst_rect.top); 01336 01337 if (FAILED(hr = IDirectDrawClipper_GetClipList(&dst_surface->clipper->IDirectDrawClipper_iface, 01338 &dst_rect, NULL, &clip_list_size))) 01339 { 01340 WARN("Failed to get clip list size, hr %#x.\n", hr); 01341 return hr; 01342 } 01343 01344 if (!(clip_list = HeapAlloc(GetProcessHeap(), 0, clip_list_size))) 01345 { 01346 WARN("Failed to allocate clip list.\n"); 01347 return E_OUTOFMEMORY; 01348 } 01349 01350 if (FAILED(hr = IDirectDrawClipper_GetClipList(&dst_surface->clipper->IDirectDrawClipper_iface, 01351 &dst_rect, clip_list, &clip_list_size))) 01352 { 01353 WARN("Failed to get clip list, hr %#x.\n", hr); 01354 HeapFree(GetProcessHeap(), 0, clip_list); 01355 return hr; 01356 } 01357 01358 clip_rect = (RECT *)clip_list->Buffer; 01359 for (i = 0; i < clip_list->rdh.nCount; ++i) 01360 { 01361 RECT src_rect_clipped = src_rect; 01362 01363 if (src_surface) 01364 { 01365 src_rect_clipped.left += (LONG)((clip_rect[i].left - dst_rect.left) * scale_x); 01366 src_rect_clipped.top += (LONG)((clip_rect[i].top - dst_rect.top) * scale_y); 01367 src_rect_clipped.right -= (LONG)((dst_rect.right - clip_rect[i].right) * scale_x); 01368 src_rect_clipped.bottom -= (LONG)((dst_rect.bottom - clip_rect[i].bottom) * scale_y); 01369 01370 if (src_surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_FRONTBUFFER) 01371 { 01372 if (FAILED(hr = ddraw_surface_update_frontbuffer(src_surface, &src_rect_clipped, TRUE))) 01373 break; 01374 } 01375 } 01376 01377 if (FAILED(hr = wined3d_surface_blt(dst_surface->wined3d_surface, &clip_rect[i], 01378 wined3d_src_surface, &src_rect_clipped, flags, fx, filter))) 01379 break; 01380 01381 if (dst_surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_FRONTBUFFER) 01382 { 01383 if (FAILED(hr = ddraw_surface_update_frontbuffer(dst_surface, &clip_rect[i], FALSE))) 01384 break; 01385 } 01386 } 01387 01388 HeapFree(GetProcessHeap(), 0, clip_list); 01389 return hr; 01390 } 01391 01392 /***************************************************************************** 01393 * IDirectDrawSurface7::Blt 01394 * 01395 * Performs a blit on the surface 01396 * 01397 * Params: 01398 * DestRect: Destination rectangle, can be NULL 01399 * SrcSurface: Source surface, can be NULL 01400 * SrcRect: Source rectangle, can be NULL 01401 * Flags: Blt flags 01402 * DDBltFx: Some extended blt parameters, connected to the flags 01403 * 01404 * Returns: 01405 * D3D_OK on success 01406 * See IWineD3DSurface::Blt for more details 01407 * 01408 *****************************************************************************/ 01409 static HRESULT WINAPI ddraw_surface7_Blt(IDirectDrawSurface7 *iface, RECT *DestRect, 01410 IDirectDrawSurface7 *SrcSurface, RECT *SrcRect, DWORD Flags, DDBLTFX *DDBltFx) 01411 { 01412 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface7(iface); 01413 IDirectDrawSurfaceImpl *Src = unsafe_impl_from_IDirectDrawSurface7(SrcSurface); 01414 HRESULT hr = DD_OK; 01415 01416 TRACE("iface %p, dst_rect %s, src_surface %p, src_rect %s, flags %#x, fx %p.\n", 01417 iface, wine_dbgstr_rect(DestRect), SrcSurface, wine_dbgstr_rect(SrcRect), Flags, DDBltFx); 01418 01419 /* Check for validity of the flags here. WineD3D Has the software-opengl selection path and would have 01420 * to check at 2 places, and sometimes do double checks. This also saves the call to wined3d :-) 01421 */ 01422 if((Flags & DDBLT_KEYSRCOVERRIDE) && (!DDBltFx || Flags & DDBLT_KEYSRC)) { 01423 WARN("Invalid source color key parameters, returning DDERR_INVALIDPARAMS\n"); 01424 return DDERR_INVALIDPARAMS; 01425 } 01426 01427 if((Flags & DDBLT_KEYDESTOVERRIDE) && (!DDBltFx || Flags & DDBLT_KEYDEST)) { 01428 WARN("Invalid destination color key parameters, returning DDERR_INVALIDPARAMS\n"); 01429 return DDERR_INVALIDPARAMS; 01430 } 01431 01432 wined3d_mutex_lock(); 01433 01434 if(Flags & DDBLT_KEYSRC && (!Src || !(Src->surface_desc.dwFlags & DDSD_CKSRCBLT))) { 01435 WARN("DDBLT_KEYDEST blit without color key in surface, returning DDERR_INVALIDPARAMS\n"); 01436 wined3d_mutex_unlock(); 01437 return DDERR_INVALIDPARAMS; 01438 } 01439 01440 /* TODO: Check if the DDBltFx contains any ddraw surface pointers. If it 01441 * does, copy the struct, and replace the ddraw surfaces with the wined3d 01442 * surfaces. So far no blitting operations using surfaces in the bltfx 01443 * struct are supported anyway. */ 01444 hr = ddraw_surface_blt_clipped(This, DestRect, Src, SrcRect, 01445 Flags, (WINEDDBLTFX *)DDBltFx, WINED3D_TEXF_LINEAR); 01446 01447 wined3d_mutex_unlock(); 01448 switch(hr) 01449 { 01450 case WINED3DERR_NOTAVAILABLE: return DDERR_UNSUPPORTED; 01451 case WINED3DERR_WRONGTEXTUREFORMAT: return DDERR_INVALIDPIXELFORMAT; 01452 default: return hr; 01453 } 01454 } 01455 01456 static HRESULT WINAPI ddraw_surface4_Blt(IDirectDrawSurface4 *iface, RECT *dst_rect, 01457 IDirectDrawSurface4 *src_surface, RECT *src_rect, DWORD flags, DDBLTFX *fx) 01458 { 01459 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface4(iface); 01460 IDirectDrawSurfaceImpl *src = unsafe_impl_from_IDirectDrawSurface4(src_surface); 01461 TRACE("iface %p, dst_rect %s, src_surface %p, src_rect %s, flags %#x, fx %p.\n", 01462 iface, wine_dbgstr_rect(dst_rect), src_surface, wine_dbgstr_rect(src_rect), flags, fx); 01463 01464 return ddraw_surface7_Blt(&This->IDirectDrawSurface7_iface, dst_rect, 01465 src ? &src->IDirectDrawSurface7_iface : NULL, src_rect, flags, fx); 01466 } 01467 01468 static HRESULT WINAPI ddraw_surface3_Blt(IDirectDrawSurface3 *iface, RECT *dst_rect, 01469 IDirectDrawSurface3 *src_surface, RECT *src_rect, DWORD flags, DDBLTFX *fx) 01470 { 01471 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface3(iface); 01472 IDirectDrawSurfaceImpl *src_impl = unsafe_impl_from_IDirectDrawSurface3(src_surface); 01473 TRACE("iface %p, dst_rect %s, src_surface %p, src_rect %s, flags %#x, fx %p.\n", 01474 iface, wine_dbgstr_rect(dst_rect), src_surface, wine_dbgstr_rect(src_rect), flags, fx); 01475 01476 return ddraw_surface7_Blt(&This->IDirectDrawSurface7_iface, dst_rect, 01477 src_impl ? &src_impl->IDirectDrawSurface7_iface : NULL, src_rect, flags, fx); 01478 } 01479 01480 static HRESULT WINAPI ddraw_surface2_Blt(IDirectDrawSurface2 *iface, RECT *dst_rect, 01481 IDirectDrawSurface2 *src_surface, RECT *src_rect, DWORD flags, DDBLTFX *fx) 01482 { 01483 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface2(iface); 01484 IDirectDrawSurfaceImpl *src_impl = unsafe_impl_from_IDirectDrawSurface2(src_surface); 01485 TRACE("iface %p, dst_rect %s, src_surface %p, src_rect %s, flags %#x, fx %p.\n", 01486 iface, wine_dbgstr_rect(dst_rect), src_surface, wine_dbgstr_rect(src_rect), flags, fx); 01487 01488 return ddraw_surface7_Blt(&This->IDirectDrawSurface7_iface, dst_rect, 01489 src_impl ? &src_impl->IDirectDrawSurface7_iface : NULL, src_rect, flags, fx); 01490 } 01491 01492 static HRESULT WINAPI ddraw_surface1_Blt(IDirectDrawSurface *iface, RECT *dst_rect, 01493 IDirectDrawSurface *src_surface, RECT *src_rect, DWORD flags, DDBLTFX *fx) 01494 { 01495 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface(iface); 01496 IDirectDrawSurfaceImpl *src_impl = unsafe_impl_from_IDirectDrawSurface(src_surface); 01497 TRACE("iface %p, dst_rect %s, src_surface %p, src_rect %s, flags %#x, fx %p.\n", 01498 iface, wine_dbgstr_rect(dst_rect), src_surface, wine_dbgstr_rect(src_rect), flags, fx); 01499 01500 return ddraw_surface7_Blt(&This->IDirectDrawSurface7_iface, dst_rect, 01501 src_impl ? &src_impl->IDirectDrawSurface7_iface : NULL, src_rect, flags, fx); 01502 } 01503 01504 /***************************************************************************** 01505 * IDirectDrawSurface7::AddAttachedSurface 01506 * 01507 * Attaches a surface to another surface. How the surface attachments work 01508 * is not totally understood yet, and this method is prone to problems. 01509 * The surface that is attached is AddRef-ed. 01510 * 01511 * Tests with complex surfaces suggest that the surface attachments form a 01512 * tree, but no method to test this has been found yet. 01513 * 01514 * The attachment list consists of a first surface (first_attached) and 01515 * for each surface a pointer to the next attached surface (next_attached). 01516 * For the first surface, and a surface that has no attachments 01517 * first_attached points to the surface itself. A surface that has 01518 * no successors in the chain has next_attached set to NULL. 01519 * 01520 * Newly attached surfaces are attached right after the root surface. 01521 * If a surface is attached to a complex surface compound, it's attached to 01522 * the surface that the app requested, not the complex root. See 01523 * GetAttachedSurface for a description how surfaces are found. 01524 * 01525 * This is how the current implementation works, and it was coded by looking 01526 * at the needs of the applications. 01527 * 01528 * So far only Z-Buffer attachments are tested, and they are activated in 01529 * WineD3D. Mipmaps could be tricky to activate in WineD3D. 01530 * Back buffers should work in 2D mode, but they are not tested(They can be 01531 * attached in older iface versions). Rendering to the front buffer and 01532 * switching between that and double buffering is not yet implemented in 01533 * WineD3D, so for 3D it might have unexpected results. 01534 * 01535 * ddraw_surface_attach_surface is the real thing, 01536 * ddraw_surface7_AddAttachedSurface is a wrapper around it that 01537 * performs additional checks. Version 7 of this interface is much more restrictive 01538 * than its predecessors. 01539 * 01540 * Params: 01541 * Attach: Surface to attach to iface 01542 * 01543 * Returns: 01544 * DD_OK on success 01545 * DDERR_CANNOTATTACHSURFACE if the surface can't be attached for some reason 01546 * 01547 *****************************************************************************/ 01548 static HRESULT ddraw_surface_attach_surface(IDirectDrawSurfaceImpl *This, IDirectDrawSurfaceImpl *Surf) 01549 { 01550 TRACE("surface %p, attachment %p.\n", This, Surf); 01551 01552 if(Surf == This) 01553 return DDERR_CANNOTATTACHSURFACE; /* unchecked */ 01554 01555 wined3d_mutex_lock(); 01556 01557 /* Check if the surface is already attached somewhere */ 01558 if (Surf->next_attached || Surf->first_attached != Surf) 01559 { 01560 /* TODO: Test for the structure of the manual attachment. Is it a 01561 * chain or a list? What happens if one surface is attached to 2 01562 * different surfaces? */ 01563 WARN("Surface %p is already attached somewhere. next_attached %p, first_attached %p.\n", 01564 Surf, Surf->next_attached, Surf->first_attached); 01565 01566 wined3d_mutex_unlock(); 01567 return DDERR_SURFACEALREADYATTACHED; 01568 } 01569 01570 /* This inserts the new surface at the 2nd position in the chain, right after the root surface */ 01571 Surf->next_attached = This->next_attached; 01572 Surf->first_attached = This->first_attached; 01573 This->next_attached = Surf; 01574 01575 /* Check if the WineD3D depth stencil needs updating */ 01576 if(This->ddraw->d3ddevice) 01577 { 01578 IDirect3DDeviceImpl_UpdateDepthStencil(This->ddraw->d3ddevice); 01579 } 01580 01581 wined3d_mutex_unlock(); 01582 01583 return DD_OK; 01584 } 01585 01586 static HRESULT WINAPI ddraw_surface7_AddAttachedSurface(IDirectDrawSurface7 *iface, IDirectDrawSurface7 *attachment) 01587 { 01588 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface7(iface); 01589 IDirectDrawSurfaceImpl *attachment_impl = unsafe_impl_from_IDirectDrawSurface7(attachment); 01590 HRESULT hr; 01591 01592 TRACE("iface %p, attachment %p.\n", iface, attachment); 01593 01594 /* Version 7 of this interface seems to refuse everything except z buffers, as per msdn */ 01595 if(!(attachment_impl->surface_desc.ddsCaps.dwCaps & DDSCAPS_ZBUFFER)) 01596 { 01597 01598 WARN("Application tries to attach a non Z buffer surface. caps %08x\n", 01599 attachment_impl->surface_desc.ddsCaps.dwCaps); 01600 return DDERR_CANNOTATTACHSURFACE; 01601 } 01602 01603 hr = ddraw_surface_attach_surface(This, attachment_impl); 01604 if (FAILED(hr)) 01605 { 01606 return hr; 01607 } 01608 ddraw_surface7_AddRef(attachment); 01609 attachment_impl->attached_iface = (IUnknown *)attachment; 01610 return hr; 01611 } 01612 01613 static HRESULT WINAPI ddraw_surface4_AddAttachedSurface(IDirectDrawSurface4 *iface, IDirectDrawSurface4 *attachment) 01614 { 01615 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface4(iface); 01616 IDirectDrawSurfaceImpl *attachment_impl = unsafe_impl_from_IDirectDrawSurface4(attachment); 01617 HRESULT hr; 01618 01619 TRACE("iface %p, attachment %p.\n", iface, attachment); 01620 01621 hr = ddraw_surface7_AddAttachedSurface(&This->IDirectDrawSurface7_iface, 01622 attachment_impl ? &attachment_impl->IDirectDrawSurface7_iface : NULL); 01623 if (FAILED(hr)) 01624 { 01625 return hr; 01626 } 01627 ddraw_surface4_AddRef(attachment); 01628 ddraw_surface7_Release(&attachment_impl->IDirectDrawSurface7_iface); 01629 attachment_impl->attached_iface = (IUnknown *)attachment; 01630 return hr; 01631 } 01632 static HRESULT WINAPI ddraw_surface3_AddAttachedSurface(IDirectDrawSurface3 *iface, IDirectDrawSurface3 *attachment) 01633 { 01634 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface3(iface); 01635 IDirectDrawSurfaceImpl *attachment_impl = unsafe_impl_from_IDirectDrawSurface3(attachment); 01636 HRESULT hr; 01637 01638 TRACE("iface %p, attachment %p.\n", iface, attachment); 01639 01640 /* Tests suggest that 01641 * -> offscreen plain surfaces can be attached to other offscreen plain surfaces 01642 * -> offscreen plain surfaces can be attached to primaries 01643 * -> primaries can be attached to offscreen plain surfaces 01644 * -> z buffers can be attached to primaries */ 01645 if (This->surface_desc.ddsCaps.dwCaps & (DDSCAPS_PRIMARYSURFACE | DDSCAPS_OFFSCREENPLAIN) 01646 && attachment_impl->surface_desc.ddsCaps.dwCaps & (DDSCAPS_PRIMARYSURFACE | DDSCAPS_OFFSCREENPLAIN)) 01647 { 01648 /* Sizes have to match */ 01649 if (attachment_impl->surface_desc.dwWidth != This->surface_desc.dwWidth 01650 || attachment_impl->surface_desc.dwHeight != This->surface_desc.dwHeight) 01651 { 01652 WARN("Surface sizes do not match.\n"); 01653 return DDERR_CANNOTATTACHSURFACE; 01654 } 01655 /* OK */ 01656 } 01657 else if (This->surface_desc.ddsCaps.dwCaps & (DDSCAPS_PRIMARYSURFACE | DDSCAPS_3DDEVICE) 01658 && attachment_impl->surface_desc.ddsCaps.dwCaps & (DDSCAPS_ZBUFFER)) 01659 { 01660 /* OK */ 01661 } 01662 else 01663 { 01664 WARN("Invalid attachment combination.\n"); 01665 return DDERR_CANNOTATTACHSURFACE; 01666 } 01667 01668 hr = ddraw_surface_attach_surface(This, attachment_impl); 01669 if (FAILED(hr)) 01670 { 01671 return hr; 01672 } 01673 ddraw_surface3_AddRef(attachment); 01674 attachment_impl->attached_iface = (IUnknown *)attachment; 01675 return hr; 01676 } 01677 01678 static HRESULT WINAPI ddraw_surface2_AddAttachedSurface(IDirectDrawSurface2 *iface, IDirectDrawSurface2 *attachment) 01679 { 01680 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface2(iface); 01681 IDirectDrawSurfaceImpl *attachment_impl = unsafe_impl_from_IDirectDrawSurface2(attachment); 01682 HRESULT hr; 01683 01684 TRACE("iface %p, attachment %p.\n", iface, attachment); 01685 01686 hr = ddraw_surface3_AddAttachedSurface(&This->IDirectDrawSurface3_iface, 01687 attachment_impl ? &attachment_impl->IDirectDrawSurface3_iface : NULL); 01688 if (FAILED(hr)) 01689 { 01690 return hr; 01691 } 01692 ddraw_surface2_AddRef(attachment); 01693 ddraw_surface3_Release(&attachment_impl->IDirectDrawSurface3_iface); 01694 attachment_impl->attached_iface = (IUnknown *)attachment; 01695 return hr; 01696 } 01697 01698 static HRESULT WINAPI ddraw_surface1_AddAttachedSurface(IDirectDrawSurface *iface, IDirectDrawSurface *attachment) 01699 { 01700 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface(iface); 01701 IDirectDrawSurfaceImpl *attachment_impl = unsafe_impl_from_IDirectDrawSurface(attachment); 01702 HRESULT hr; 01703 01704 TRACE("iface %p, attachment %p.\n", iface, attachment); 01705 01706 hr = ddraw_surface3_AddAttachedSurface(&This->IDirectDrawSurface3_iface, 01707 attachment_impl ? &attachment_impl->IDirectDrawSurface3_iface : NULL); 01708 if (FAILED(hr)) 01709 { 01710 return hr; 01711 } 01712 ddraw_surface1_AddRef(attachment); 01713 ddraw_surface3_Release(&attachment_impl->IDirectDrawSurface3_iface); 01714 attachment_impl->attached_iface = (IUnknown *)attachment; 01715 return hr; 01716 } 01717 01718 /***************************************************************************** 01719 * IDirectDrawSurface7::DeleteAttachedSurface 01720 * 01721 * Removes a surface from the attachment chain. The surface's refcount 01722 * is decreased by one after it has been removed 01723 * 01724 * Params: 01725 * Flags: Some flags, not used by this implementation 01726 * Attach: Surface to detach 01727 * 01728 * Returns: 01729 * DD_OK on success 01730 * DDERR_SURFACENOTATTACHED if the surface isn't attached to 01731 * 01732 *****************************************************************************/ 01733 static HRESULT ddraw_surface_delete_attached_surface(IDirectDrawSurfaceImpl *This, 01734 IDirectDrawSurfaceImpl *Surf, IUnknown *detach_iface) 01735 { 01736 IDirectDrawSurfaceImpl *Prev = This; 01737 01738 TRACE("surface %p, attachment %p, detach_iface %p.\n", This, Surf, detach_iface); 01739 01740 wined3d_mutex_lock(); 01741 if (!Surf || (Surf->first_attached != This) || (Surf == This) ) 01742 { 01743 wined3d_mutex_unlock(); 01744 return DDERR_CANNOTDETACHSURFACE; 01745 } 01746 01747 if (Surf->attached_iface != detach_iface) 01748 { 01749 WARN("Surf->attach_iface %p != detach_iface %p.\n", Surf->attached_iface, detach_iface); 01750 wined3d_mutex_unlock(); 01751 return DDERR_SURFACENOTATTACHED; 01752 } 01753 01754 /* Remove MIPMAPSUBLEVEL if this seemed to be one */ 01755 if (This->surface_desc.ddsCaps.dwCaps & 01756 Surf->surface_desc.ddsCaps.dwCaps & DDSCAPS_MIPMAP) 01757 { 01758 Surf->surface_desc.ddsCaps.dwCaps2 &= ~DDSCAPS2_MIPMAPSUBLEVEL; 01759 /* FIXME: we should probably also subtract from dwMipMapCount of this 01760 * and all parent surfaces */ 01761 } 01762 01763 /* Find the predecessor of the detached surface */ 01764 while(Prev) 01765 { 01766 if(Prev->next_attached == Surf) break; 01767 Prev = Prev->next_attached; 01768 } 01769 01770 /* There must be a surface, otherwise there's a bug */ 01771 assert(Prev != NULL); 01772 01773 /* Unchain the surface */ 01774 Prev->next_attached = Surf->next_attached; 01775 Surf->next_attached = NULL; 01776 Surf->first_attached = Surf; 01777 01778 /* Check if the WineD3D depth stencil needs updating */ 01779 if(This->ddraw->d3ddevice) 01780 { 01781 IDirect3DDeviceImpl_UpdateDepthStencil(This->ddraw->d3ddevice); 01782 } 01783 wined3d_mutex_unlock(); 01784 01785 /* Set attached_iface to NULL before releasing it, the surface may go 01786 * away. */ 01787 Surf->attached_iface = NULL; 01788 IUnknown_Release(detach_iface); 01789 01790 return DD_OK; 01791 } 01792 01793 static HRESULT WINAPI ddraw_surface7_DeleteAttachedSurface(IDirectDrawSurface7 *iface, 01794 DWORD flags, IDirectDrawSurface7 *attachment) 01795 { 01796 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface7(iface); 01797 IDirectDrawSurfaceImpl *attachment_impl = unsafe_impl_from_IDirectDrawSurface7(attachment); 01798 01799 TRACE("iface %p, flags %#x, attachment %p.\n", iface, flags, attachment); 01800 01801 return ddraw_surface_delete_attached_surface(This, attachment_impl, (IUnknown *)attachment); 01802 } 01803 01804 static HRESULT WINAPI ddraw_surface4_DeleteAttachedSurface(IDirectDrawSurface4 *iface, 01805 DWORD flags, IDirectDrawSurface4 *attachment) 01806 { 01807 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface4(iface); 01808 IDirectDrawSurfaceImpl *attachment_impl = unsafe_impl_from_IDirectDrawSurface4(attachment); 01809 01810 TRACE("iface %p, flags %#x, attachment %p.\n", iface, flags, attachment); 01811 01812 return ddraw_surface_delete_attached_surface(This, attachment_impl, (IUnknown *)attachment); 01813 } 01814 01815 static HRESULT WINAPI ddraw_surface3_DeleteAttachedSurface(IDirectDrawSurface3 *iface, 01816 DWORD flags, IDirectDrawSurface3 *attachment) 01817 { 01818 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface3(iface); 01819 IDirectDrawSurfaceImpl *attachment_impl = unsafe_impl_from_IDirectDrawSurface3(attachment); 01820 01821 TRACE("iface %p, flags %#x, attachment %p.\n", iface, flags, attachment); 01822 01823 return ddraw_surface_delete_attached_surface(This, attachment_impl, (IUnknown *)attachment); 01824 } 01825 01826 static HRESULT WINAPI ddraw_surface2_DeleteAttachedSurface(IDirectDrawSurface2 *iface, 01827 DWORD flags, IDirectDrawSurface2 *attachment) 01828 { 01829 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface2(iface); 01830 IDirectDrawSurfaceImpl *attachment_impl = unsafe_impl_from_IDirectDrawSurface2(attachment); 01831 01832 TRACE("iface %p, flags %#x, attachment %p.\n", iface, flags, attachment); 01833 01834 return ddraw_surface_delete_attached_surface(This, attachment_impl, (IUnknown *)attachment); 01835 } 01836 01837 static HRESULT WINAPI ddraw_surface1_DeleteAttachedSurface(IDirectDrawSurface *iface, 01838 DWORD flags, IDirectDrawSurface *attachment) 01839 { 01840 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface(iface); 01841 IDirectDrawSurfaceImpl *attachment_impl = unsafe_impl_from_IDirectDrawSurface(attachment); 01842 01843 TRACE("iface %p, flags %#x, attachment %p.\n", iface, flags, attachment); 01844 01845 return ddraw_surface_delete_attached_surface(This, attachment_impl, (IUnknown *)attachment); 01846 } 01847 01848 /***************************************************************************** 01849 * IDirectDrawSurface7::AddOverlayDirtyRect 01850 * 01851 * "This method is not currently implemented" 01852 * 01853 * Params: 01854 * Rect: ? 01855 * 01856 * Returns: 01857 * DDERR_UNSUPPORTED 01858 * 01859 *****************************************************************************/ 01860 static HRESULT WINAPI ddraw_surface7_AddOverlayDirtyRect(IDirectDrawSurface7 *iface, RECT *Rect) 01861 { 01862 TRACE("iface %p, rect %s.\n", iface, wine_dbgstr_rect(Rect)); 01863 01864 return DDERR_UNSUPPORTED; /* unchecked */ 01865 } 01866 01867 static HRESULT WINAPI ddraw_surface4_AddOverlayDirtyRect(IDirectDrawSurface4 *iface, RECT *rect) 01868 { 01869 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface4(iface); 01870 TRACE("iface %p, rect %s.\n", iface, wine_dbgstr_rect(rect)); 01871 01872 return ddraw_surface7_AddOverlayDirtyRect(&This->IDirectDrawSurface7_iface, rect); 01873 } 01874 01875 static HRESULT WINAPI ddraw_surface3_AddOverlayDirtyRect(IDirectDrawSurface3 *iface, RECT *rect) 01876 { 01877 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface3(iface); 01878 TRACE("iface %p, rect %s.\n", iface, wine_dbgstr_rect(rect)); 01879 01880 return ddraw_surface7_AddOverlayDirtyRect(&This->IDirectDrawSurface7_iface, rect); 01881 } 01882 01883 static HRESULT WINAPI ddraw_surface2_AddOverlayDirtyRect(IDirectDrawSurface2 *iface, RECT *rect) 01884 { 01885 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface2(iface); 01886 TRACE("iface %p, rect %s.\n", iface, wine_dbgstr_rect(rect)); 01887 01888 return ddraw_surface7_AddOverlayDirtyRect(&This->IDirectDrawSurface7_iface, rect); 01889 } 01890 01891 static HRESULT WINAPI ddraw_surface1_AddOverlayDirtyRect(IDirectDrawSurface *iface, RECT *rect) 01892 { 01893 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface(iface); 01894 TRACE("iface %p, rect %s.\n", iface, wine_dbgstr_rect(rect)); 01895 01896 return ddraw_surface7_AddOverlayDirtyRect(&This->IDirectDrawSurface7_iface, rect); 01897 } 01898 01899 /***************************************************************************** 01900 * IDirectDrawSurface7::GetDC 01901 * 01902 * Returns a GDI device context for the surface 01903 * 01904 * Params: 01905 * hdc: Address of a HDC variable to store the dc to 01906 * 01907 * Returns: 01908 * DD_OK on success 01909 * DDERR_INVALIDPARAMS if hdc is NULL 01910 * For details, see IWineD3DSurface::GetDC 01911 * 01912 *****************************************************************************/ 01913 static HRESULT WINAPI ddraw_surface7_GetDC(IDirectDrawSurface7 *iface, HDC *hdc) 01914 { 01915 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface7(iface); 01916 HRESULT hr = DD_OK; 01917 01918 TRACE("iface %p, dc %p.\n", iface, hdc); 01919 01920 if(!hdc) 01921 return DDERR_INVALIDPARAMS; 01922 01923 wined3d_mutex_lock(); 01924 if (This->surface_desc.ddsCaps.dwCaps & DDSCAPS_FRONTBUFFER) 01925 hr = ddraw_surface_update_frontbuffer(This, NULL, TRUE); 01926 if (SUCCEEDED(hr)) 01927 hr = wined3d_surface_getdc(This->wined3d_surface, hdc); 01928 wined3d_mutex_unlock(); 01929 switch(hr) 01930 { 01931 /* Some, but not all errors set *hdc to NULL. E.g. DCALREADYCREATED does not 01932 * touch *hdc 01933 */ 01934 case WINED3DERR_INVALIDCALL: 01935 if(hdc) *hdc = NULL; 01936 return DDERR_INVALIDPARAMS; 01937 01938 default: return hr; 01939 } 01940 } 01941 01942 static HRESULT WINAPI ddraw_surface4_GetDC(IDirectDrawSurface4 *iface, HDC *dc) 01943 { 01944 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface4(iface); 01945 TRACE("iface %p, dc %p.\n", iface, dc); 01946 01947 return ddraw_surface7_GetDC(&This->IDirectDrawSurface7_iface, dc); 01948 } 01949 01950 static HRESULT WINAPI ddraw_surface3_GetDC(IDirectDrawSurface3 *iface, HDC *dc) 01951 { 01952 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface3(iface); 01953 TRACE("iface %p, dc %p.\n", iface, dc); 01954 01955 return ddraw_surface7_GetDC(&This->IDirectDrawSurface7_iface, dc); 01956 } 01957 01958 static HRESULT WINAPI ddraw_surface2_GetDC(IDirectDrawSurface2 *iface, HDC *dc) 01959 { 01960 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface2(iface); 01961 TRACE("iface %p, dc %p.\n", iface, dc); 01962 01963 return ddraw_surface7_GetDC(&This->IDirectDrawSurface7_iface, dc); 01964 } 01965 01966 static HRESULT WINAPI ddraw_surface1_GetDC(IDirectDrawSurface *iface, HDC *dc) 01967 { 01968 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface(iface); 01969 TRACE("iface %p, dc %p.\n", iface, dc); 01970 01971 return ddraw_surface7_GetDC(&This->IDirectDrawSurface7_iface, dc); 01972 } 01973 01974 /***************************************************************************** 01975 * IDirectDrawSurface7::ReleaseDC 01976 * 01977 * Releases the DC that was constructed with GetDC 01978 * 01979 * Params: 01980 * hdc: HDC to release 01981 * 01982 * Returns: 01983 * DD_OK on success 01984 * For more details, see IWineD3DSurface::ReleaseDC 01985 * 01986 *****************************************************************************/ 01987 static HRESULT WINAPI ddraw_surface7_ReleaseDC(IDirectDrawSurface7 *iface, HDC hdc) 01988 { 01989 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface7(iface); 01990 HRESULT hr; 01991 01992 TRACE("iface %p, dc %p.\n", iface, hdc); 01993 01994 wined3d_mutex_lock(); 01995 hr = wined3d_surface_releasedc(This->wined3d_surface, hdc); 01996 if (SUCCEEDED(hr) && (This->surface_desc.ddsCaps.dwCaps & DDSCAPS_FRONTBUFFER)) 01997 hr = ddraw_surface_update_frontbuffer(This, NULL, FALSE); 01998 wined3d_mutex_unlock(); 01999 02000 return hr; 02001 } 02002 02003 static HRESULT WINAPI ddraw_surface4_ReleaseDC(IDirectDrawSurface4 *iface, HDC dc) 02004 { 02005 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface4(iface); 02006 TRACE("iface %p, dc %p.\n", iface, dc); 02007 02008 return ddraw_surface7_ReleaseDC(&This->IDirectDrawSurface7_iface, dc); 02009 } 02010 02011 static HRESULT WINAPI ddraw_surface3_ReleaseDC(IDirectDrawSurface3 *iface, HDC dc) 02012 { 02013 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface3(iface); 02014 TRACE("iface %p, dc %p.\n", iface, dc); 02015 02016 return ddraw_surface7_ReleaseDC(&This->IDirectDrawSurface7_iface, dc); 02017 } 02018 02019 static HRESULT WINAPI ddraw_surface2_ReleaseDC(IDirectDrawSurface2 *iface, HDC dc) 02020 { 02021 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface2(iface); 02022 TRACE("iface %p, dc %p.\n", iface, dc); 02023 02024 return ddraw_surface7_ReleaseDC(&This->IDirectDrawSurface7_iface, dc); 02025 } 02026 02027 static HRESULT WINAPI ddraw_surface1_ReleaseDC(IDirectDrawSurface *iface, HDC dc) 02028 { 02029 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface(iface); 02030 TRACE("iface %p, dc %p.\n", iface, dc); 02031 02032 return ddraw_surface7_ReleaseDC(&This->IDirectDrawSurface7_iface, dc); 02033 } 02034 02035 /***************************************************************************** 02036 * IDirectDrawSurface7::GetCaps 02037 * 02038 * Returns the surface's caps 02039 * 02040 * Params: 02041 * Caps: Address to write the caps to 02042 * 02043 * Returns: 02044 * DD_OK on success 02045 * DDERR_INVALIDPARAMS if Caps is NULL 02046 * 02047 *****************************************************************************/ 02048 static HRESULT WINAPI ddraw_surface7_GetCaps(IDirectDrawSurface7 *iface, DDSCAPS2 *Caps) 02049 { 02050 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface7(iface); 02051 02052 TRACE("iface %p, caps %p.\n", iface, Caps); 02053 02054 if(!Caps) 02055 return DDERR_INVALIDPARAMS; 02056 02057 *Caps = This->surface_desc.ddsCaps; 02058 return DD_OK; 02059 } 02060 02061 static HRESULT WINAPI ddraw_surface4_GetCaps(IDirectDrawSurface4 *iface, DDSCAPS2 *caps) 02062 { 02063 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface4(iface); 02064 TRACE("iface %p, caps %p.\n", iface, caps); 02065 02066 return ddraw_surface7_GetCaps(&This->IDirectDrawSurface7_iface, caps); 02067 } 02068 02069 static HRESULT WINAPI ddraw_surface3_GetCaps(IDirectDrawSurface3 *iface, DDSCAPS *caps) 02070 { 02071 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface3(iface); 02072 DDSCAPS2 caps2; 02073 HRESULT hr; 02074 02075 TRACE("iface %p, caps %p.\n", iface, caps); 02076 02077 hr = ddraw_surface7_GetCaps(&This->IDirectDrawSurface7_iface, &caps2); 02078 if (FAILED(hr)) return hr; 02079 02080 caps->dwCaps = caps2.dwCaps; 02081 return hr; 02082 } 02083 02084 static HRESULT WINAPI ddraw_surface2_GetCaps(IDirectDrawSurface2 *iface, DDSCAPS *caps) 02085 { 02086 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface2(iface); 02087 DDSCAPS2 caps2; 02088 HRESULT hr; 02089 02090 TRACE("iface %p, caps %p.\n", iface, caps); 02091 02092 hr = ddraw_surface7_GetCaps(&This->IDirectDrawSurface7_iface, &caps2); 02093 if (FAILED(hr)) return hr; 02094 02095 caps->dwCaps = caps2.dwCaps; 02096 return hr; 02097 } 02098 02099 static HRESULT WINAPI ddraw_surface1_GetCaps(IDirectDrawSurface *iface, DDSCAPS *caps) 02100 { 02101 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface(iface); 02102 DDSCAPS2 caps2; 02103 HRESULT hr; 02104 02105 TRACE("iface %p, caps %p.\n", iface, caps); 02106 02107 hr = ddraw_surface7_GetCaps(&This->IDirectDrawSurface7_iface, &caps2); 02108 if (FAILED(hr)) return hr; 02109 02110 caps->dwCaps = caps2.dwCaps; 02111 return hr; 02112 } 02113 02114 /***************************************************************************** 02115 * IDirectDrawSurface7::SetPriority 02116 * 02117 * Sets a texture priority for managed textures. 02118 * 02119 * Params: 02120 * Priority: The new priority 02121 * 02122 * Returns: 02123 * DD_OK on success 02124 * For more details, see IWineD3DSurface::SetPriority 02125 * 02126 *****************************************************************************/ 02127 static HRESULT WINAPI ddraw_surface7_SetPriority(IDirectDrawSurface7 *iface, DWORD Priority) 02128 { 02129 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface7(iface); 02130 HRESULT hr; 02131 02132 TRACE("iface %p, priority %u.\n", iface, Priority); 02133 02134 wined3d_mutex_lock(); 02135 hr = wined3d_surface_set_priority(This->wined3d_surface, Priority); 02136 wined3d_mutex_unlock(); 02137 02138 return hr; 02139 } 02140 02141 /***************************************************************************** 02142 * IDirectDrawSurface7::GetPriority 02143 * 02144 * Returns the surface's priority 02145 * 02146 * Params: 02147 * Priority: Address of a variable to write the priority to 02148 * 02149 * Returns: 02150 * D3D_OK on success 02151 * DDERR_INVALIDPARAMS if Priority == NULL 02152 * For more details, see IWineD3DSurface::GetPriority 02153 * 02154 *****************************************************************************/ 02155 static HRESULT WINAPI ddraw_surface7_GetPriority(IDirectDrawSurface7 *iface, DWORD *Priority) 02156 { 02157 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface7(iface); 02158 02159 TRACE("iface %p, priority %p.\n", iface, Priority); 02160 02161 if(!Priority) 02162 { 02163 return DDERR_INVALIDPARAMS; 02164 } 02165 02166 wined3d_mutex_lock(); 02167 *Priority = wined3d_surface_get_priority(This->wined3d_surface); 02168 wined3d_mutex_unlock(); 02169 02170 return DD_OK; 02171 } 02172 02173 /***************************************************************************** 02174 * IDirectDrawSurface7::SetPrivateData 02175 * 02176 * Stores some data in the surface that is intended for the application's 02177 * use. 02178 * 02179 * Params: 02180 * tag: GUID that identifies the data 02181 * Data: Pointer to the private data 02182 * Size: Size of the private data 02183 * Flags: Some flags 02184 * 02185 * Returns: 02186 * D3D_OK on success 02187 * For more details, see IWineD3DSurface::SetPrivateData 02188 * 02189 *****************************************************************************/ 02190 static HRESULT WINAPI ddraw_surface7_SetPrivateData(IDirectDrawSurface7 *iface, 02191 REFGUID tag, void *Data, DWORD Size, DWORD Flags) 02192 { 02193 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface7(iface); 02194 struct wined3d_resource *resource; 02195 HRESULT hr; 02196 02197 TRACE("iface %p, tag %s, data %p, data_size %u, flags %#x.\n", 02198 iface, debugstr_guid(tag), Data, Size, Flags); 02199 02200 wined3d_mutex_lock(); 02201 resource = wined3d_surface_get_resource(This->wined3d_surface); 02202 hr = wined3d_resource_set_private_data(resource, tag, Data, Size, Flags); 02203 wined3d_mutex_unlock(); 02204 02205 switch(hr) 02206 { 02207 case WINED3DERR_INVALIDCALL: return DDERR_INVALIDPARAMS; 02208 default: return hr; 02209 } 02210 } 02211 02212 static HRESULT WINAPI ddraw_surface4_SetPrivateData(IDirectDrawSurface4 *iface, 02213 REFGUID tag, void *data, DWORD size, DWORD flags) 02214 { 02215 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface4(iface); 02216 TRACE("iface %p, tag %s, data %p, data_size %u, flags %#x.\n", 02217 iface, debugstr_guid(tag), data, size, flags); 02218 02219 return ddraw_surface7_SetPrivateData(&This->IDirectDrawSurface7_iface, tag, data, size, flags); 02220 } 02221 02222 /***************************************************************************** 02223 * IDirectDrawSurface7::GetPrivateData 02224 * 02225 * Returns the private data set with IDirectDrawSurface7::SetPrivateData 02226 * 02227 * Params: 02228 * tag: GUID of the data to return 02229 * Data: Address where to write the data to 02230 * Size: Size of the buffer at Data 02231 * 02232 * Returns: 02233 * DD_OK on success 02234 * DDERR_INVALIDPARAMS if Data is NULL 02235 * For more details, see IWineD3DSurface::GetPrivateData 02236 * 02237 *****************************************************************************/ 02238 static HRESULT WINAPI ddraw_surface7_GetPrivateData(IDirectDrawSurface7 *iface, REFGUID tag, void *Data, DWORD *Size) 02239 { 02240 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface7(iface); 02241 struct wined3d_resource *resource; 02242 HRESULT hr; 02243 02244 TRACE("iface %p, tag %s, data %p, data_size %p.\n", 02245 iface, debugstr_guid(tag), Data, Size); 02246 02247 if(!Data) 02248 return DDERR_INVALIDPARAMS; 02249 02250 wined3d_mutex_lock(); 02251 resource = wined3d_surface_get_resource(This->wined3d_surface); 02252 hr = wined3d_resource_get_private_data(resource, tag, Data, Size); 02253 wined3d_mutex_unlock(); 02254 02255 return hr; 02256 } 02257 02258 static HRESULT WINAPI ddraw_surface4_GetPrivateData(IDirectDrawSurface4 *iface, REFGUID tag, void *data, DWORD *size) 02259 { 02260 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface4(iface); 02261 TRACE("iface %p, tag %s, data %p, data_size %p.\n", 02262 iface, debugstr_guid(tag), data, size); 02263 02264 return ddraw_surface7_GetPrivateData(&This->IDirectDrawSurface7_iface, tag, data, size); 02265 } 02266 02267 /***************************************************************************** 02268 * IDirectDrawSurface7::FreePrivateData 02269 * 02270 * Frees private data stored in the surface 02271 * 02272 * Params: 02273 * tag: Tag of the data to free 02274 * 02275 * Returns: 02276 * D3D_OK on success 02277 * For more details, see IWineD3DSurface::FreePrivateData 02278 * 02279 *****************************************************************************/ 02280 static HRESULT WINAPI ddraw_surface7_FreePrivateData(IDirectDrawSurface7 *iface, REFGUID tag) 02281 { 02282 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface7(iface); 02283 struct wined3d_resource *resource; 02284 HRESULT hr; 02285 02286 TRACE("iface %p, tag %s.\n", iface, debugstr_guid(tag)); 02287 02288 wined3d_mutex_lock(); 02289 resource = wined3d_surface_get_resource(This->wined3d_surface); 02290 hr = wined3d_resource_free_private_data(resource, tag); 02291 wined3d_mutex_unlock(); 02292 02293 return hr; 02294 } 02295 02296 static HRESULT WINAPI ddraw_surface4_FreePrivateData(IDirectDrawSurface4 *iface, REFGUID tag) 02297 { 02298 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface4(iface); 02299 TRACE("iface %p, tag %s.\n", iface, debugstr_guid(tag)); 02300 02301 return ddraw_surface7_FreePrivateData(&This->IDirectDrawSurface7_iface, tag); 02302 } 02303 02304 /***************************************************************************** 02305 * IDirectDrawSurface7::PageLock 02306 * 02307 * Prevents a sysmem surface from being paged out 02308 * 02309 * Params: 02310 * Flags: Not used, must be 0(unchecked) 02311 * 02312 * Returns: 02313 * DD_OK, because it's a stub 02314 * 02315 *****************************************************************************/ 02316 static HRESULT WINAPI ddraw_surface7_PageLock(IDirectDrawSurface7 *iface, DWORD Flags) 02317 { 02318 TRACE("iface %p, flags %#x.\n", iface, Flags); 02319 02320 /* This is Windows memory management related - we don't need this */ 02321 return DD_OK; 02322 } 02323 02324 static HRESULT WINAPI ddraw_surface4_PageLock(IDirectDrawSurface4 *iface, DWORD flags) 02325 { 02326 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface4(iface); 02327 TRACE("iface %p, flags %#x.\n", iface, flags); 02328 02329 return ddraw_surface7_PageLock(&This->IDirectDrawSurface7_iface, flags); 02330 } 02331 02332 static HRESULT WINAPI ddraw_surface3_PageLock(IDirectDrawSurface3 *iface, DWORD flags) 02333 { 02334 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface3(iface); 02335 TRACE("iface %p, flags %#x.\n", iface, flags); 02336 02337 return ddraw_surface7_PageLock(&This->IDirectDrawSurface7_iface, flags); 02338 } 02339 02340 static HRESULT WINAPI ddraw_surface2_PageLock(IDirectDrawSurface2 *iface, DWORD flags) 02341 { 02342 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface2(iface); 02343 TRACE("iface %p, flags %#x.\n", iface, flags); 02344 02345 return ddraw_surface7_PageLock(&This->IDirectDrawSurface7_iface, flags); 02346 } 02347 02348 /***************************************************************************** 02349 * IDirectDrawSurface7::PageUnlock 02350 * 02351 * Allows a sysmem surface to be paged out 02352 * 02353 * Params: 02354 * Flags: Not used, must be 0(unchecked) 02355 * 02356 * Returns: 02357 * DD_OK, because it's a stub 02358 * 02359 *****************************************************************************/ 02360 static HRESULT WINAPI ddraw_surface7_PageUnlock(IDirectDrawSurface7 *iface, DWORD Flags) 02361 { 02362 TRACE("iface %p, flags %#x.\n", iface, Flags); 02363 02364 return DD_OK; 02365 } 02366 02367 static HRESULT WINAPI ddraw_surface4_PageUnlock(IDirectDrawSurface4 *iface, DWORD flags) 02368 { 02369 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface4(iface); 02370 TRACE("iface %p, flags %#x.\n", iface, flags); 02371 02372 return ddraw_surface7_PageUnlock(&This->IDirectDrawSurface7_iface, flags); 02373 } 02374 02375 static HRESULT WINAPI ddraw_surface3_PageUnlock(IDirectDrawSurface3 *iface, DWORD flags) 02376 { 02377 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface3(iface); 02378 TRACE("iface %p, flags %#x.\n", iface, flags); 02379 02380 return ddraw_surface7_PageUnlock(&This->IDirectDrawSurface7_iface, flags); 02381 } 02382 02383 static HRESULT WINAPI ddraw_surface2_PageUnlock(IDirectDrawSurface2 *iface, DWORD flags) 02384 { 02385 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface2(iface); 02386 TRACE("iface %p, flags %#x.\n", iface, flags); 02387 02388 return ddraw_surface7_PageUnlock(&This->IDirectDrawSurface7_iface, flags); 02389 } 02390 02391 /***************************************************************************** 02392 * IDirectDrawSurface7::BltBatch 02393 * 02394 * An unimplemented function 02395 * 02396 * Params: 02397 * ? 02398 * 02399 * Returns: 02400 * DDERR_UNSUPPORTED 02401 * 02402 *****************************************************************************/ 02403 static HRESULT WINAPI ddraw_surface7_BltBatch(IDirectDrawSurface7 *iface, DDBLTBATCH *Batch, DWORD Count, DWORD Flags) 02404 { 02405 TRACE("iface %p, batch %p, count %u, flags %#x.\n", iface, Batch, Count, Flags); 02406 02407 /* MSDN: "not currently implemented" */ 02408 return DDERR_UNSUPPORTED; 02409 } 02410 02411 static HRESULT WINAPI ddraw_surface4_BltBatch(IDirectDrawSurface4 *iface, DDBLTBATCH *batch, DWORD count, DWORD flags) 02412 { 02413 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface4(iface); 02414 TRACE("iface %p, batch %p, count %u, flags %#x.\n", iface, batch, count, flags); 02415 02416 return ddraw_surface7_BltBatch(&This->IDirectDrawSurface7_iface, batch, count, flags); 02417 } 02418 02419 static HRESULT WINAPI ddraw_surface3_BltBatch(IDirectDrawSurface3 *iface, DDBLTBATCH *batch, DWORD count, DWORD flags) 02420 { 02421 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface3(iface); 02422 TRACE("iface %p, batch %p, count %u, flags %#x.\n", iface, batch, count, flags); 02423 02424 return ddraw_surface7_BltBatch(&This->IDirectDrawSurface7_iface, batch, count, flags); 02425 } 02426 02427 static HRESULT WINAPI ddraw_surface2_BltBatch(IDirectDrawSurface2 *iface, DDBLTBATCH *batch, DWORD count, DWORD flags) 02428 { 02429 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface2(iface); 02430 TRACE("iface %p, batch %p, count %u, flags %#x.\n", iface, batch, count, flags); 02431 02432 return ddraw_surface7_BltBatch(&This->IDirectDrawSurface7_iface, batch, count, flags); 02433 } 02434 02435 static HRESULT WINAPI ddraw_surface1_BltBatch(IDirectDrawSurface *iface, DDBLTBATCH *batch, DWORD count, DWORD flags) 02436 { 02437 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface(iface); 02438 TRACE("iface %p, batch %p, count %u, flags %#x.\n", iface, batch, count, flags); 02439 02440 return ddraw_surface7_BltBatch(&This->IDirectDrawSurface7_iface, batch, count, flags); 02441 } 02442 02443 /***************************************************************************** 02444 * IDirectDrawSurface7::EnumAttachedSurfaces 02445 * 02446 * Enumerates all surfaces attached to this surface 02447 * 02448 * Params: 02449 * context: Pointer to pass unmodified to the callback 02450 * cb: Callback function to call for each surface 02451 * 02452 * Returns: 02453 * DD_OK on success 02454 * DDERR_INVALIDPARAMS if cb is NULL 02455 * 02456 *****************************************************************************/ 02457 static HRESULT WINAPI ddraw_surface7_EnumAttachedSurfaces(IDirectDrawSurface7 *iface, 02458 void *context, LPDDENUMSURFACESCALLBACK7 cb) 02459 { 02460 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface7(iface); 02461 IDirectDrawSurfaceImpl *surf; 02462 DDSURFACEDESC2 desc; 02463 int i; 02464 02465 /* Attached surfaces aren't handled in WineD3D */ 02466 TRACE("iface %p, context %p, callback %p.\n", iface, context, cb); 02467 02468 if(!cb) 02469 return DDERR_INVALIDPARAMS; 02470 02471 wined3d_mutex_lock(); 02472 02473 for(i = 0; i < MAX_COMPLEX_ATTACHED; i++) 02474 { 02475 surf = This->complex_array[i]; 02476 if(!surf) break; 02477 02478 ddraw_surface7_AddRef(&surf->IDirectDrawSurface7_iface); 02479 desc = surf->surface_desc; 02480 /* check: != DDENUMRET_OK or == DDENUMRET_CANCEL? */ 02481 if (cb(&surf->IDirectDrawSurface7_iface, &desc, context) == DDENUMRET_CANCEL) 02482 { 02483 wined3d_mutex_unlock(); 02484 return DD_OK; 02485 } 02486 } 02487 02488 for (surf = This->next_attached; surf != NULL; surf = surf->next_attached) 02489 { 02490 ddraw_surface7_AddRef(&surf->IDirectDrawSurface7_iface); 02491 desc = surf->surface_desc; 02492 /* check: != DDENUMRET_OK or == DDENUMRET_CANCEL? */ 02493 if (cb(&surf->IDirectDrawSurface7_iface, &desc, context) == DDENUMRET_CANCEL) 02494 { 02495 wined3d_mutex_unlock(); 02496 return DD_OK; 02497 } 02498 } 02499 02500 TRACE(" end of enumeration.\n"); 02501 02502 wined3d_mutex_unlock(); 02503 02504 return DD_OK; 02505 } 02506 02507 struct callback_info2 02508 { 02509 LPDDENUMSURFACESCALLBACK2 callback; 02510 void *context; 02511 }; 02512 02513 struct callback_info 02514 { 02515 LPDDENUMSURFACESCALLBACK callback; 02516 void *context; 02517 }; 02518 02519 static HRESULT CALLBACK EnumCallback2(IDirectDrawSurface7 *surface, DDSURFACEDESC2 *surface_desc, void *context) 02520 { 02521 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface7(surface); 02522 const struct callback_info2 *info = context; 02523 02524 ddraw_surface4_AddRef(&This->IDirectDrawSurface4_iface); 02525 ddraw_surface7_Release(surface); 02526 02527 return info->callback(&This->IDirectDrawSurface4_iface, surface_desc, info->context); 02528 } 02529 02530 static HRESULT CALLBACK EnumCallback(IDirectDrawSurface7 *surface, DDSURFACEDESC2 *surface_desc, void *context) 02531 { 02532 IDirectDrawSurfaceImpl *surface_impl = impl_from_IDirectDrawSurface7(surface); 02533 const struct callback_info *info = context; 02534 02535 ddraw_surface1_AddRef(&surface_impl->IDirectDrawSurface_iface); 02536 ddraw_surface7_Release(surface); 02537 02538 /* FIXME: Check surface_test.dwSize */ 02539 return info->callback(&surface_impl->IDirectDrawSurface_iface, 02540 (DDSURFACEDESC *)surface_desc, info->context); 02541 } 02542 02543 static HRESULT WINAPI ddraw_surface4_EnumAttachedSurfaces(IDirectDrawSurface4 *iface, 02544 void *context, LPDDENUMSURFACESCALLBACK2 callback) 02545 { 02546 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface4(iface); 02547 struct callback_info2 info; 02548 02549 TRACE("iface %p, context %p, callback %p.\n", iface, context, callback); 02550 02551 info.callback = callback; 02552 info.context = context; 02553 02554 return ddraw_surface7_EnumAttachedSurfaces(&This->IDirectDrawSurface7_iface, 02555 &info, EnumCallback2); 02556 } 02557 02558 static HRESULT WINAPI ddraw_surface3_EnumAttachedSurfaces(IDirectDrawSurface3 *iface, 02559 void *context, LPDDENUMSURFACESCALLBACK callback) 02560 { 02561 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface3(iface); 02562 struct callback_info info; 02563 02564 TRACE("iface %p, context %p, callback %p.\n", iface, context, callback); 02565 02566 info.callback = callback; 02567 info.context = context; 02568 02569 return ddraw_surface7_EnumAttachedSurfaces(&This->IDirectDrawSurface7_iface, 02570 &info, EnumCallback); 02571 } 02572 02573 static HRESULT WINAPI ddraw_surface2_EnumAttachedSurfaces(IDirectDrawSurface2 *iface, 02574 void *context, LPDDENUMSURFACESCALLBACK callback) 02575 { 02576 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface2(iface); 02577 struct callback_info info; 02578 02579 TRACE("iface %p, context %p, callback %p.\n", iface, context, callback); 02580 02581 info.callback = callback; 02582 info.context = context; 02583 02584 return ddraw_surface7_EnumAttachedSurfaces(&This->IDirectDrawSurface7_iface, 02585 &info, EnumCallback); 02586 } 02587 02588 static HRESULT WINAPI ddraw_surface1_EnumAttachedSurfaces(IDirectDrawSurface *iface, 02589 void *context, LPDDENUMSURFACESCALLBACK callback) 02590 { 02591 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface(iface); 02592 struct callback_info info; 02593 02594 TRACE("iface %p, context %p, callback %p.\n", iface, context, callback); 02595 02596 info.callback = callback; 02597 info.context = context; 02598 02599 return ddraw_surface7_EnumAttachedSurfaces(&This->IDirectDrawSurface7_iface, 02600 &info, EnumCallback); 02601 } 02602 02603 /***************************************************************************** 02604 * IDirectDrawSurface7::EnumOverlayZOrders 02605 * 02606 * "Enumerates the overlay surfaces on the specified destination" 02607 * 02608 * Params: 02609 * Flags: DDENUMOVERLAYZ_BACKTOFRONT or DDENUMOVERLAYZ_FRONTTOBACK 02610 * context: context to pass back to the callback 02611 * cb: callback function to call for each enumerated surface 02612 * 02613 * Returns: 02614 * DD_OK, because it's a stub 02615 * 02616 *****************************************************************************/ 02617 static HRESULT WINAPI ddraw_surface7_EnumOverlayZOrders(IDirectDrawSurface7 *iface, 02618 DWORD Flags, void *context, LPDDENUMSURFACESCALLBACK7 cb) 02619 { 02620 FIXME("iface %p, flags %#x, context %p, callback %p stub!\n", iface, Flags, context, cb); 02621 02622 return DD_OK; 02623 } 02624 02625 static HRESULT WINAPI ddraw_surface4_EnumOverlayZOrders(IDirectDrawSurface4 *iface, 02626 DWORD flags, void *context, LPDDENUMSURFACESCALLBACK2 callback) 02627 { 02628 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface4(iface); 02629 struct callback_info2 info; 02630 02631 TRACE("iface %p, flags %#x, context %p, callback %p.\n", iface, flags, context, callback); 02632 02633 info.callback = callback; 02634 info.context = context; 02635 02636 return ddraw_surface7_EnumOverlayZOrders(&This->IDirectDrawSurface7_iface, 02637 flags, &info, EnumCallback2); 02638 } 02639 02640 static HRESULT WINAPI ddraw_surface3_EnumOverlayZOrders(IDirectDrawSurface3 *iface, 02641 DWORD flags, void *context, LPDDENUMSURFACESCALLBACK callback) 02642 { 02643 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface3(iface); 02644 struct callback_info info; 02645 02646 TRACE("iface %p, flags %#x, context %p, callback %p.\n", iface, flags, context, callback); 02647 02648 info.callback = callback; 02649 info.context = context; 02650 02651 return ddraw_surface7_EnumOverlayZOrders(&This->IDirectDrawSurface7_iface, 02652 flags, &info, EnumCallback); 02653 } 02654 02655 static HRESULT WINAPI ddraw_surface2_EnumOverlayZOrders(IDirectDrawSurface2 *iface, 02656 DWORD flags, void *context, LPDDENUMSURFACESCALLBACK callback) 02657 { 02658 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface2(iface); 02659 struct callback_info info; 02660 02661 TRACE("iface %p, flags %#x, context %p, callback %p.\n", iface, flags, context, callback); 02662 02663 info.callback = callback; 02664 info.context = context; 02665 02666 return ddraw_surface7_EnumOverlayZOrders(&This->IDirectDrawSurface7_iface, 02667 flags, &info, EnumCallback); 02668 } 02669 02670 static HRESULT WINAPI ddraw_surface1_EnumOverlayZOrders(IDirectDrawSurface *iface, 02671 DWORD flags, void *context, LPDDENUMSURFACESCALLBACK callback) 02672 { 02673 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface(iface); 02674 struct callback_info info; 02675 02676 TRACE("iface %p, flags %#x, context %p, callback %p.\n", iface, flags, context, callback); 02677 02678 info.callback = callback; 02679 info.context = context; 02680 02681 return ddraw_surface7_EnumOverlayZOrders(&This->IDirectDrawSurface7_iface, 02682 flags, &info, EnumCallback); 02683 } 02684 02685 /***************************************************************************** 02686 * IDirectDrawSurface7::GetBltStatus 02687 * 02688 * Returns the blitting status 02689 * 02690 * Params: 02691 * Flags: DDGBS_CANBLT or DDGBS_ISBLTDONE 02692 * 02693 * Returns: 02694 * See IWineD3DSurface::Blt 02695 * 02696 *****************************************************************************/ 02697 static HRESULT WINAPI ddraw_surface7_GetBltStatus(IDirectDrawSurface7 *iface, DWORD Flags) 02698 { 02699 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface7(iface); 02700 HRESULT hr; 02701 02702 TRACE("iface %p, flags %#x.\n", iface, Flags); 02703 02704 wined3d_mutex_lock(); 02705 hr = wined3d_surface_get_blt_status(This->wined3d_surface, Flags); 02706 wined3d_mutex_unlock(); 02707 switch(hr) 02708 { 02709 case WINED3DERR_INVALIDCALL: return DDERR_INVALIDPARAMS; 02710 default: return hr; 02711 } 02712 } 02713 02714 static HRESULT WINAPI ddraw_surface4_GetBltStatus(IDirectDrawSurface4 *iface, DWORD flags) 02715 { 02716 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface4(iface); 02717 TRACE("iface %p, flags %#x.\n", iface, flags); 02718 02719 return ddraw_surface7_GetBltStatus(&This->IDirectDrawSurface7_iface, flags); 02720 } 02721 02722 static HRESULT WINAPI ddraw_surface3_GetBltStatus(IDirectDrawSurface3 *iface, DWORD flags) 02723 { 02724 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface3(iface); 02725 TRACE("iface %p, flags %#x.\n", iface, flags); 02726 02727 return ddraw_surface7_GetBltStatus(&This->IDirectDrawSurface7_iface, flags); 02728 } 02729 02730 static HRESULT WINAPI ddraw_surface2_GetBltStatus(IDirectDrawSurface2 *iface, DWORD flags) 02731 { 02732 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface2(iface); 02733 TRACE("iface %p, flags %#x.\n", iface, flags); 02734 02735 return ddraw_surface7_GetBltStatus(&This->IDirectDrawSurface7_iface, flags); 02736 } 02737 02738 static HRESULT WINAPI ddraw_surface1_GetBltStatus(IDirectDrawSurface *iface, DWORD flags) 02739 { 02740 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface(iface); 02741 TRACE("iface %p, flags %#x.\n", iface, flags); 02742 02743 return ddraw_surface7_GetBltStatus(&This->IDirectDrawSurface7_iface, flags); 02744 } 02745 02746 /***************************************************************************** 02747 * IDirectDrawSurface7::GetColorKey 02748 * 02749 * Returns the color key assigned to the surface 02750 * 02751 * Params: 02752 * Flags: Some flags 02753 * CKey: Address to store the key to 02754 * 02755 * Returns: 02756 * DD_OK on success 02757 * DDERR_INVALIDPARAMS if CKey is NULL 02758 * 02759 *****************************************************************************/ 02760 static HRESULT WINAPI ddraw_surface7_GetColorKey(IDirectDrawSurface7 *iface, DWORD Flags, DDCOLORKEY *CKey) 02761 { 02762 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface7(iface); 02763 02764 TRACE("iface %p, flags %#x, color_key %p.\n", iface, Flags, CKey); 02765 02766 if(!CKey) 02767 return DDERR_INVALIDPARAMS; 02768 02769 wined3d_mutex_lock(); 02770 02771 switch (Flags) 02772 { 02773 case DDCKEY_DESTBLT: 02774 if (!(This->surface_desc.dwFlags & DDSD_CKDESTBLT)) 02775 { 02776 wined3d_mutex_unlock(); 02777 return DDERR_NOCOLORKEY; 02778 } 02779 *CKey = This->surface_desc.ddckCKDestBlt; 02780 break; 02781 02782 case DDCKEY_DESTOVERLAY: 02783 if (!(This->surface_desc.dwFlags & DDSD_CKDESTOVERLAY)) 02784 { 02785 wined3d_mutex_unlock(); 02786 return DDERR_NOCOLORKEY; 02787 } 02788 *CKey = This->surface_desc.u3.ddckCKDestOverlay; 02789 break; 02790 02791 case DDCKEY_SRCBLT: 02792 if (!(This->surface_desc.dwFlags & DDSD_CKSRCBLT)) 02793 { 02794 wined3d_mutex_unlock(); 02795 return DDERR_NOCOLORKEY; 02796 } 02797 *CKey = This->surface_desc.ddckCKSrcBlt; 02798 break; 02799 02800 case DDCKEY_SRCOVERLAY: 02801 if (!(This->surface_desc.dwFlags & DDSD_CKSRCOVERLAY)) 02802 { 02803 wined3d_mutex_unlock(); 02804 return DDERR_NOCOLORKEY; 02805 } 02806 *CKey = This->surface_desc.ddckCKSrcOverlay; 02807 break; 02808 02809 default: 02810 wined3d_mutex_unlock(); 02811 return DDERR_INVALIDPARAMS; 02812 } 02813 02814 wined3d_mutex_unlock(); 02815 02816 return DD_OK; 02817 } 02818 02819 static HRESULT WINAPI ddraw_surface4_GetColorKey(IDirectDrawSurface4 *iface, DWORD flags, DDCOLORKEY *color_key) 02820 { 02821 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface4(iface); 02822 TRACE("iface %p, flags %#x, color_key %p.\n", iface, flags, color_key); 02823 02824 return ddraw_surface7_GetColorKey(&This->IDirectDrawSurface7_iface, flags, color_key); 02825 } 02826 02827 static HRESULT WINAPI ddraw_surface3_GetColorKey(IDirectDrawSurface3 *iface, DWORD flags, DDCOLORKEY *color_key) 02828 { 02829 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface3(iface); 02830 TRACE("iface %p, flags %#x, color_key %p.\n", iface, flags, color_key); 02831 02832 return ddraw_surface7_GetColorKey(&This->IDirectDrawSurface7_iface, flags, color_key); 02833 } 02834 02835 static HRESULT WINAPI ddraw_surface2_GetColorKey(IDirectDrawSurface2 *iface, DWORD flags, DDCOLORKEY *color_key) 02836 { 02837 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface2(iface); 02838 TRACE("iface %p, flags %#x, color_key %p.\n", iface, flags, color_key); 02839 02840 return ddraw_surface7_GetColorKey(&This->IDirectDrawSurface7_iface, flags, color_key); 02841 } 02842 02843 static HRESULT WINAPI ddraw_surface1_GetColorKey(IDirectDrawSurface *iface, DWORD flags, DDCOLORKEY *color_key) 02844 { 02845 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface(iface); 02846 TRACE("iface %p, flags %#x, color_key %p.\n", iface, flags, color_key); 02847 02848 return ddraw_surface7_GetColorKey(&This->IDirectDrawSurface7_iface, flags, color_key); 02849 } 02850 02851 /***************************************************************************** 02852 * IDirectDrawSurface7::GetFlipStatus 02853 * 02854 * Returns the flipping status of the surface 02855 * 02856 * Params: 02857 * Flags: DDGFS_CANFLIP of DDGFS_ISFLIPDONE 02858 * 02859 * Returns: 02860 * See IWineD3DSurface::GetFlipStatus 02861 * 02862 *****************************************************************************/ 02863 static HRESULT WINAPI ddraw_surface7_GetFlipStatus(IDirectDrawSurface7 *iface, DWORD Flags) 02864 { 02865 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface7(iface); 02866 HRESULT hr; 02867 02868 TRACE("iface %p, flags %#x.\n", iface, Flags); 02869 02870 wined3d_mutex_lock(); 02871 hr = wined3d_surface_get_flip_status(This->wined3d_surface, Flags); 02872 wined3d_mutex_unlock(); 02873 02874 switch(hr) 02875 { 02876 case WINED3DERR_INVALIDCALL: return DDERR_INVALIDPARAMS; 02877 default: return hr; 02878 } 02879 } 02880 02881 static HRESULT WINAPI ddraw_surface4_GetFlipStatus(IDirectDrawSurface4 *iface, DWORD flags) 02882 { 02883 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface4(iface); 02884 TRACE("iface %p, flags %#x.\n", iface, flags); 02885 02886 return ddraw_surface7_GetFlipStatus(&This->IDirectDrawSurface7_iface, flags); 02887 } 02888 02889 static HRESULT WINAPI ddraw_surface3_GetFlipStatus(IDirectDrawSurface3 *iface, DWORD flags) 02890 { 02891 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface3(iface); 02892 TRACE("iface %p, flags %#x.\n", iface, flags); 02893 02894 return ddraw_surface7_GetFlipStatus(&This->IDirectDrawSurface7_iface, flags); 02895 } 02896 02897 static HRESULT WINAPI ddraw_surface2_GetFlipStatus(IDirectDrawSurface2 *iface, DWORD flags) 02898 { 02899 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface2(iface); 02900 TRACE("iface %p, flags %#x.\n", iface, flags); 02901 02902 return ddraw_surface7_GetFlipStatus(&This->IDirectDrawSurface7_iface, flags); 02903 } 02904 02905 static HRESULT WINAPI ddraw_surface1_GetFlipStatus(IDirectDrawSurface *iface, DWORD flags) 02906 { 02907 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface(iface); 02908 TRACE("iface %p, flags %#x.\n", iface, flags); 02909 02910 return ddraw_surface7_GetFlipStatus(&This->IDirectDrawSurface7_iface, flags); 02911 } 02912 02913 /***************************************************************************** 02914 * IDirectDrawSurface7::GetOverlayPosition 02915 * 02916 * Returns the display coordinates of a visible and active overlay surface 02917 * 02918 * Params: 02919 * X 02920 * Y 02921 * 02922 * Returns: 02923 * DDERR_NOTAOVERLAYSURFACE, because it's a stub 02924 *****************************************************************************/ 02925 static HRESULT WINAPI ddraw_surface7_GetOverlayPosition(IDirectDrawSurface7 *iface, LONG *X, LONG *Y) 02926 { 02927 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface7(iface); 02928 HRESULT hr; 02929 02930 TRACE("iface %p, x %p, y %p.\n", iface, X, Y); 02931 02932 wined3d_mutex_lock(); 02933 hr = wined3d_surface_get_overlay_position(This->wined3d_surface, X, Y); 02934 wined3d_mutex_unlock(); 02935 02936 return hr; 02937 } 02938 02939 static HRESULT WINAPI ddraw_surface4_GetOverlayPosition(IDirectDrawSurface4 *iface, LONG *x, LONG *y) 02940 { 02941 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface4(iface); 02942 TRACE("iface %p, x %p, y %p.\n", iface, x, y); 02943 02944 return ddraw_surface7_GetOverlayPosition(&This->IDirectDrawSurface7_iface, x, y); 02945 } 02946 02947 static HRESULT WINAPI ddraw_surface3_GetOverlayPosition(IDirectDrawSurface3 *iface, LONG *x, LONG *y) 02948 { 02949 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface3(iface); 02950 TRACE("iface %p, x %p, y %p.\n", iface, x, y); 02951 02952 return ddraw_surface7_GetOverlayPosition(&This->IDirectDrawSurface7_iface, x, y); 02953 } 02954 02955 static HRESULT WINAPI ddraw_surface2_GetOverlayPosition(IDirectDrawSurface2 *iface, LONG *x, LONG *y) 02956 { 02957 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface2(iface); 02958 TRACE("iface %p, x %p, y %p.\n", iface, x, y); 02959 02960 return ddraw_surface7_GetOverlayPosition(&This->IDirectDrawSurface7_iface, x, y); 02961 } 02962 02963 static HRESULT WINAPI ddraw_surface1_GetOverlayPosition(IDirectDrawSurface *iface, LONG *x, LONG *y) 02964 { 02965 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface(iface); 02966 TRACE("iface %p, x %p, y %p.\n", iface, x, y); 02967 02968 return ddraw_surface7_GetOverlayPosition(&This->IDirectDrawSurface7_iface, x, y); 02969 } 02970 02971 /***************************************************************************** 02972 * IDirectDrawSurface7::GetPixelFormat 02973 * 02974 * Returns the pixel format of the Surface 02975 * 02976 * Params: 02977 * PixelFormat: Pointer to a DDPIXELFORMAT structure to which the pixel 02978 * format should be written 02979 * 02980 * Returns: 02981 * DD_OK on success 02982 * DDERR_INVALIDPARAMS if PixelFormat is NULL 02983 * 02984 *****************************************************************************/ 02985 static HRESULT WINAPI ddraw_surface7_GetPixelFormat(IDirectDrawSurface7 *iface, DDPIXELFORMAT *PixelFormat) 02986 { 02987 /* What is DDERR_INVALIDSURFACETYPE for here? */ 02988 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface7(iface); 02989 02990 TRACE("iface %p, pixel_format %p.\n", iface, PixelFormat); 02991 02992 if(!PixelFormat) 02993 return DDERR_INVALIDPARAMS; 02994 02995 wined3d_mutex_lock(); 02996 DD_STRUCT_COPY_BYSIZE(PixelFormat,&This->surface_desc.u4.ddpfPixelFormat); 02997 wined3d_mutex_unlock(); 02998 02999 return DD_OK; 03000 } 03001 03002 static HRESULT WINAPI ddraw_surface4_GetPixelFormat(IDirectDrawSurface4 *iface, DDPIXELFORMAT *pixel_format) 03003 { 03004 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface4(iface); 03005 TRACE("iface %p, pixel_format %p.\n", iface, pixel_format); 03006 03007 return ddraw_surface7_GetPixelFormat(&This->IDirectDrawSurface7_iface, pixel_format); 03008 } 03009 03010 static HRESULT WINAPI ddraw_surface3_GetPixelFormat(IDirectDrawSurface3 *iface, DDPIXELFORMAT *pixel_format) 03011 { 03012 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface3(iface); 03013 TRACE("iface %p, pixel_format %p.\n", iface, pixel_format); 03014 03015 return ddraw_surface7_GetPixelFormat(&This->IDirectDrawSurface7_iface, pixel_format); 03016 } 03017 03018 static HRESULT WINAPI ddraw_surface2_GetPixelFormat(IDirectDrawSurface2 *iface, DDPIXELFORMAT *pixel_format) 03019 { 03020 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface2(iface); 03021 TRACE("iface %p, pixel_format %p.\n", iface, pixel_format); 03022 03023 return ddraw_surface7_GetPixelFormat(&This->IDirectDrawSurface7_iface, pixel_format); 03024 } 03025 03026 static HRESULT WINAPI ddraw_surface1_GetPixelFormat(IDirectDrawSurface *iface, DDPIXELFORMAT *pixel_format) 03027 { 03028 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface(iface); 03029 TRACE("iface %p, pixel_format %p.\n", iface, pixel_format); 03030 03031 return ddraw_surface7_GetPixelFormat(&This->IDirectDrawSurface7_iface, pixel_format); 03032 } 03033 03034 /***************************************************************************** 03035 * IDirectDrawSurface7::GetSurfaceDesc 03036 * 03037 * Returns the description of this surface 03038 * 03039 * Params: 03040 * DDSD: Address of a DDSURFACEDESC2 structure that is to be filled with the 03041 * surface desc 03042 * 03043 * Returns: 03044 * DD_OK on success 03045 * DDERR_INVALIDPARAMS if DDSD is NULL 03046 * 03047 *****************************************************************************/ 03048 static HRESULT WINAPI ddraw_surface7_GetSurfaceDesc(IDirectDrawSurface7 *iface, DDSURFACEDESC2 *DDSD) 03049 { 03050 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface7(iface); 03051 03052 TRACE("iface %p, surface_desc %p.\n", iface, DDSD); 03053 03054 if(!DDSD) 03055 return DDERR_INVALIDPARAMS; 03056 03057 if (DDSD->dwSize != sizeof(DDSURFACEDESC2)) 03058 { 03059 WARN("Incorrect struct size %d, returning DDERR_INVALIDPARAMS\n",DDSD->dwSize); 03060 return DDERR_INVALIDPARAMS; 03061 } 03062 03063 wined3d_mutex_lock(); 03064 DD_STRUCT_COPY_BYSIZE(DDSD,&This->surface_desc); 03065 TRACE("Returning surface desc:\n"); 03066 if (TRACE_ON(ddraw)) DDRAW_dump_surface_desc(DDSD); 03067 wined3d_mutex_unlock(); 03068 03069 return DD_OK; 03070 } 03071 03072 static HRESULT WINAPI ddraw_surface4_GetSurfaceDesc(IDirectDrawSurface4 *iface, DDSURFACEDESC2 *DDSD) 03073 { 03074 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface4(iface); 03075 TRACE("iface %p, surface_desc %p.\n", iface, DDSD); 03076 03077 return ddraw_surface7_GetSurfaceDesc(&This->IDirectDrawSurface7_iface, DDSD); 03078 } 03079 03080 static HRESULT WINAPI ddraw_surface3_GetSurfaceDesc(IDirectDrawSurface3 *iface, DDSURFACEDESC *surface_desc) 03081 { 03082 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface3(iface); 03083 03084 TRACE("iface %p, surface_desc %p.\n", iface, surface_desc); 03085 03086 if (!surface_desc) return DDERR_INVALIDPARAMS; 03087 03088 if (surface_desc->dwSize != sizeof(DDSURFACEDESC)) 03089 { 03090 WARN("Incorrect structure size %u, returning DDERR_INVALIDPARAMS.\n", surface_desc->dwSize); 03091 return DDERR_INVALIDPARAMS; 03092 } 03093 03094 wined3d_mutex_lock(); 03095 DDSD2_to_DDSD(&This->surface_desc, surface_desc); 03096 TRACE("Returning surface desc:\n"); 03097 if (TRACE_ON(ddraw)) 03098 { 03099 /* DDRAW_dump_surface_desc handles the smaller size */ 03100 DDRAW_dump_surface_desc((DDSURFACEDESC2 *)surface_desc); 03101 } 03102 wined3d_mutex_unlock(); 03103 03104 return DD_OK; 03105 } 03106 03107 static HRESULT WINAPI ddraw_surface2_GetSurfaceDesc(IDirectDrawSurface2 *iface, DDSURFACEDESC *DDSD) 03108 { 03109 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface2(iface); 03110 TRACE("iface %p, surface_desc %p.\n", iface, DDSD); 03111 03112 return ddraw_surface3_GetSurfaceDesc(&This->IDirectDrawSurface3_iface, DDSD); 03113 } 03114 03115 static HRESULT WINAPI ddraw_surface1_GetSurfaceDesc(IDirectDrawSurface *iface, DDSURFACEDESC *DDSD) 03116 { 03117 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface(iface); 03118 TRACE("iface %p, surface_desc %p.\n", iface, DDSD); 03119 03120 return ddraw_surface3_GetSurfaceDesc(&This->IDirectDrawSurface3_iface, DDSD); 03121 } 03122 03123 /***************************************************************************** 03124 * IDirectDrawSurface7::Initialize 03125 * 03126 * Initializes the surface. This is a no-op in Wine 03127 * 03128 * Params: 03129 * DD: Pointer to an DirectDraw interface 03130 * DDSD: Surface description for initialization 03131 * 03132 * Returns: 03133 * DDERR_ALREADYINITIALIZED 03134 * 03135 *****************************************************************************/ 03136 static HRESULT WINAPI ddraw_surface7_Initialize(IDirectDrawSurface7 *iface, 03137 IDirectDraw *ddraw, DDSURFACEDESC2 *surface_desc) 03138 { 03139 TRACE("iface %p, ddraw %p, surface_desc %p.\n", iface, ddraw, surface_desc); 03140 03141 return DDERR_ALREADYINITIALIZED; 03142 } 03143 03144 static HRESULT WINAPI ddraw_surface4_Initialize(IDirectDrawSurface4 *iface, 03145 IDirectDraw *ddraw, DDSURFACEDESC2 *surface_desc) 03146 { 03147 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface4(iface); 03148 TRACE("iface %p, ddraw %p, surface_desc %p.\n", iface, ddraw, surface_desc); 03149 03150 return ddraw_surface7_Initialize(&This->IDirectDrawSurface7_iface, 03151 ddraw, surface_desc); 03152 } 03153 03154 static HRESULT WINAPI ddraw_surface3_Initialize(IDirectDrawSurface3 *iface, 03155 IDirectDraw *ddraw, DDSURFACEDESC *surface_desc) 03156 { 03157 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface3(iface); 03158 DDSURFACEDESC2 surface_desc2; 03159 TRACE("iface %p, ddraw %p, surface_desc %p.\n", iface, ddraw, surface_desc); 03160 03161 if (surface_desc) DDSD_to_DDSD2(surface_desc, &surface_desc2); 03162 return ddraw_surface7_Initialize(&This->IDirectDrawSurface7_iface, 03163 ddraw, surface_desc ? &surface_desc2 : NULL); 03164 } 03165 03166 static HRESULT WINAPI ddraw_surface2_Initialize(IDirectDrawSurface2 *iface, 03167 IDirectDraw *ddraw, DDSURFACEDESC *surface_desc) 03168 { 03169 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface2(iface); 03170 DDSURFACEDESC2 surface_desc2; 03171 TRACE("iface %p, ddraw %p, surface_desc %p.\n", iface, ddraw, surface_desc); 03172 03173 if (surface_desc) DDSD_to_DDSD2(surface_desc, &surface_desc2); 03174 return ddraw_surface7_Initialize(&This->IDirectDrawSurface7_iface, 03175 ddraw, surface_desc ? &surface_desc2 : NULL); 03176 } 03177 03178 static HRESULT WINAPI ddraw_surface1_Initialize(IDirectDrawSurface *iface, 03179 IDirectDraw *ddraw, DDSURFACEDESC *surface_desc) 03180 { 03181 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface(iface); 03182 DDSURFACEDESC2 surface_desc2; 03183 TRACE("iface %p, ddraw %p, surface_desc %p.\n", iface, ddraw, surface_desc); 03184 03185 if (surface_desc) DDSD_to_DDSD2(surface_desc, &surface_desc2); 03186 return ddraw_surface7_Initialize(&This->IDirectDrawSurface7_iface, 03187 ddraw, surface_desc ? &surface_desc2 : NULL); 03188 } 03189 03190 /***************************************************************************** 03191 * IDirect3DTexture1::Initialize 03192 * 03193 * The sdk says it's not implemented 03194 * 03195 * Params: 03196 * ? 03197 * 03198 * Returns 03199 * DDERR_UNSUPPORTED 03200 * 03201 *****************************************************************************/ 03202 static HRESULT WINAPI d3d_texture1_Initialize(IDirect3DTexture *iface, 03203 IDirect3DDevice *device, IDirectDrawSurface *surface) 03204 { 03205 TRACE("iface %p, device %p, surface %p.\n", iface, device, surface); 03206 03207 return DDERR_UNSUPPORTED; /* Unchecked */ 03208 } 03209 03210 /***************************************************************************** 03211 * IDirectDrawSurface7::IsLost 03212 * 03213 * Checks if the surface is lost 03214 * 03215 * Returns: 03216 * DD_OK, if the surface is usable 03217 * DDERR_ISLOST if the surface is lost 03218 * See IWineD3DSurface::IsLost for more details 03219 * 03220 *****************************************************************************/ 03221 static HRESULT WINAPI ddraw_surface7_IsLost(IDirectDrawSurface7 *iface) 03222 { 03223 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface7(iface); 03224 HRESULT hr; 03225 03226 TRACE("iface %p.\n", iface); 03227 03228 wined3d_mutex_lock(); 03229 hr = wined3d_surface_is_lost(This->wined3d_surface); 03230 wined3d_mutex_unlock(); 03231 03232 switch(hr) 03233 { 03234 /* D3D8 and 9 loose full devices, thus there's only a DEVICELOST error. 03235 * WineD3D uses the same error for surfaces 03236 */ 03237 case WINED3DERR_DEVICELOST: return DDERR_SURFACELOST; 03238 default: return hr; 03239 } 03240 } 03241 03242 static HRESULT WINAPI ddraw_surface4_IsLost(IDirectDrawSurface4 *iface) 03243 { 03244 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface4(iface); 03245 TRACE("iface %p.\n", iface); 03246 03247 return ddraw_surface7_IsLost(&This->IDirectDrawSurface7_iface); 03248 } 03249 03250 static HRESULT WINAPI ddraw_surface3_IsLost(IDirectDrawSurface3 *iface) 03251 { 03252 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface3(iface); 03253 TRACE("iface %p.\n", iface); 03254 03255 return ddraw_surface7_IsLost(&This->IDirectDrawSurface7_iface); 03256 } 03257 03258 static HRESULT WINAPI ddraw_surface2_IsLost(IDirectDrawSurface2 *iface) 03259 { 03260 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface2(iface); 03261 TRACE("iface %p.\n", iface); 03262 03263 return ddraw_surface7_IsLost(&This->IDirectDrawSurface7_iface); 03264 } 03265 03266 static HRESULT WINAPI ddraw_surface1_IsLost(IDirectDrawSurface *iface) 03267 { 03268 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface(iface); 03269 TRACE("iface %p.\n", iface); 03270 03271 return ddraw_surface7_IsLost(&This->IDirectDrawSurface7_iface); 03272 } 03273 03274 /***************************************************************************** 03275 * IDirectDrawSurface7::Restore 03276 * 03277 * Restores a lost surface. This makes the surface usable again, but 03278 * doesn't reload its old contents 03279 * 03280 * Returns: 03281 * DD_OK on success 03282 * See IWineD3DSurface::Restore for more details 03283 * 03284 *****************************************************************************/ 03285 static HRESULT WINAPI ddraw_surface7_Restore(IDirectDrawSurface7 *iface) 03286 { 03287 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface7(iface); 03288 HRESULT hr; 03289 03290 TRACE("iface %p.\n", iface); 03291 03292 wined3d_mutex_lock(); 03293 hr = wined3d_surface_restore(This->wined3d_surface); 03294 wined3d_mutex_unlock(); 03295 03296 return hr; 03297 } 03298 03299 static HRESULT WINAPI ddraw_surface4_Restore(IDirectDrawSurface4 *iface) 03300 { 03301 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface4(iface); 03302 TRACE("iface %p.\n", iface); 03303 03304 return ddraw_surface7_Restore(&This->IDirectDrawSurface7_iface); 03305 } 03306 03307 static HRESULT WINAPI ddraw_surface3_Restore(IDirectDrawSurface3 *iface) 03308 { 03309 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface3(iface); 03310 TRACE("iface %p.\n", iface); 03311 03312 return ddraw_surface7_Restore(&This->IDirectDrawSurface7_iface); 03313 } 03314 03315 static HRESULT WINAPI ddraw_surface2_Restore(IDirectDrawSurface2 *iface) 03316 { 03317 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface2(iface); 03318 TRACE("iface %p.\n", iface); 03319 03320 return ddraw_surface7_Restore(&This->IDirectDrawSurface7_iface); 03321 } 03322 03323 static HRESULT WINAPI ddraw_surface1_Restore(IDirectDrawSurface *iface) 03324 { 03325 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface(iface); 03326 TRACE("iface %p.\n", iface); 03327 03328 return ddraw_surface7_Restore(&This->IDirectDrawSurface7_iface); 03329 } 03330 03331 /***************************************************************************** 03332 * IDirectDrawSurface7::SetOverlayPosition 03333 * 03334 * Changes the display coordinates of an overlay surface 03335 * 03336 * Params: 03337 * X: 03338 * Y: 03339 * 03340 * Returns: 03341 * DDERR_NOTAOVERLAYSURFACE, because we don't support overlays right now 03342 *****************************************************************************/ 03343 static HRESULT WINAPI ddraw_surface7_SetOverlayPosition(IDirectDrawSurface7 *iface, LONG X, LONG Y) 03344 { 03345 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface7(iface); 03346 HRESULT hr; 03347 03348 TRACE("iface %p, x %d, y %d.\n", iface, X, Y); 03349 03350 wined3d_mutex_lock(); 03351 hr = wined3d_surface_set_overlay_position(This->wined3d_surface, X, Y); 03352 wined3d_mutex_unlock(); 03353 03354 return hr; 03355 } 03356 03357 static HRESULT WINAPI ddraw_surface4_SetOverlayPosition(IDirectDrawSurface4 *iface, LONG x, LONG y) 03358 { 03359 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface4(iface); 03360 TRACE("iface %p, x %d, y %d.\n", iface, x, y); 03361 03362 return ddraw_surface7_SetOverlayPosition(&This->IDirectDrawSurface7_iface, x, y); 03363 } 03364 03365 static HRESULT WINAPI ddraw_surface3_SetOverlayPosition(IDirectDrawSurface3 *iface, LONG x, LONG y) 03366 { 03367 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface3(iface); 03368 TRACE("iface %p, x %d, y %d.\n", iface, x, y); 03369 03370 return ddraw_surface7_SetOverlayPosition(&This->IDirectDrawSurface7_iface, x, y); 03371 } 03372 03373 static HRESULT WINAPI ddraw_surface2_SetOverlayPosition(IDirectDrawSurface2 *iface, LONG x, LONG y) 03374 { 03375 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface2(iface); 03376 TRACE("iface %p, x %d, y %d.\n", iface, x, y); 03377 03378 return ddraw_surface7_SetOverlayPosition(&This->IDirectDrawSurface7_iface, x, y); 03379 } 03380 03381 static HRESULT WINAPI ddraw_surface1_SetOverlayPosition(IDirectDrawSurface *iface, LONG x, LONG y) 03382 { 03383 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface(iface); 03384 TRACE("iface %p, x %d, y %d.\n", iface, x, y); 03385 03386 return ddraw_surface7_SetOverlayPosition(&This->IDirectDrawSurface7_iface, x, y); 03387 } 03388 03389 /***************************************************************************** 03390 * IDirectDrawSurface7::UpdateOverlay 03391 * 03392 * Modifies the attributes of an overlay surface. 03393 * 03394 * Params: 03395 * SrcRect: The section of the source being used for the overlay 03396 * DstSurface: Address of the surface that is overlaid 03397 * DstRect: Place of the overlay 03398 * Flags: some DDOVER_* flags 03399 * 03400 * Returns: 03401 * DDERR_UNSUPPORTED, because we don't support overlays 03402 * 03403 *****************************************************************************/ 03404 static HRESULT WINAPI ddraw_surface7_UpdateOverlay(IDirectDrawSurface7 *iface, RECT *SrcRect, 03405 IDirectDrawSurface7 *DstSurface, RECT *DstRect, DWORD Flags, DDOVERLAYFX *FX) 03406 { 03407 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface7(iface); 03408 IDirectDrawSurfaceImpl *Dst = unsafe_impl_from_IDirectDrawSurface7(DstSurface); 03409 HRESULT hr; 03410 03411 TRACE("iface %p, src_rect %s, dst_surface %p, dst_rect %s, flags %#x, fx %p.\n", 03412 iface, wine_dbgstr_rect(SrcRect), DstSurface, wine_dbgstr_rect(DstRect), Flags, FX); 03413 03414 wined3d_mutex_lock(); 03415 hr = wined3d_surface_update_overlay(This->wined3d_surface, SrcRect, 03416 Dst ? Dst->wined3d_surface : NULL, DstRect, Flags, (WINEDDOVERLAYFX *)FX); 03417 wined3d_mutex_unlock(); 03418 03419 switch(hr) { 03420 case WINED3DERR_INVALIDCALL: return DDERR_INVALIDPARAMS; 03421 case WINEDDERR_NOTAOVERLAYSURFACE: return DDERR_NOTAOVERLAYSURFACE; 03422 case WINEDDERR_OVERLAYNOTVISIBLE: return DDERR_OVERLAYNOTVISIBLE; 03423 default: 03424 return hr; 03425 } 03426 } 03427 03428 static HRESULT WINAPI ddraw_surface4_UpdateOverlay(IDirectDrawSurface4 *iface, RECT *src_rect, 03429 IDirectDrawSurface4 *dst_surface, RECT *dst_rect, DWORD flags, DDOVERLAYFX *fx) 03430 { 03431 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface4(iface); 03432 IDirectDrawSurfaceImpl *dst_impl = unsafe_impl_from_IDirectDrawSurface4(dst_surface); 03433 TRACE("iface %p, src_rect %s, dst_surface %p, dst_rect %s, flags %#x, fx %p.\n", 03434 iface, wine_dbgstr_rect(src_rect), dst_surface, wine_dbgstr_rect(dst_rect), flags, fx); 03435 03436 return ddraw_surface7_UpdateOverlay(&This->IDirectDrawSurface7_iface, src_rect, 03437 dst_impl ? &dst_impl->IDirectDrawSurface7_iface : NULL, dst_rect, flags, fx); 03438 } 03439 03440 static HRESULT WINAPI ddraw_surface3_UpdateOverlay(IDirectDrawSurface3 *iface, RECT *src_rect, 03441 IDirectDrawSurface3 *dst_surface, RECT *dst_rect, DWORD flags, DDOVERLAYFX *fx) 03442 { 03443 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface3(iface); 03444 IDirectDrawSurfaceImpl *dst_impl = unsafe_impl_from_IDirectDrawSurface3(dst_surface); 03445 TRACE("iface %p, src_rect %s, dst_surface %p, dst_rect %s, flags %#x, fx %p.\n", 03446 iface, wine_dbgstr_rect(src_rect), dst_surface, wine_dbgstr_rect(dst_rect), flags, fx); 03447 03448 return ddraw_surface7_UpdateOverlay(&This->IDirectDrawSurface7_iface, src_rect, 03449 dst_impl ? &dst_impl->IDirectDrawSurface7_iface : NULL, dst_rect, flags, fx); 03450 } 03451 03452 static HRESULT WINAPI ddraw_surface2_UpdateOverlay(IDirectDrawSurface2 *iface, RECT *src_rect, 03453 IDirectDrawSurface2 *dst_surface, RECT *dst_rect, DWORD flags, DDOVERLAYFX *fx) 03454 { 03455 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface2(iface); 03456 IDirectDrawSurfaceImpl *dst_impl = unsafe_impl_from_IDirectDrawSurface2(dst_surface); 03457 TRACE("iface %p, src_rect %s, dst_surface %p, dst_rect %s, flags %#x, fx %p.\n", 03458 iface, wine_dbgstr_rect(src_rect), dst_surface, wine_dbgstr_rect(dst_rect), flags, fx); 03459 03460 return ddraw_surface7_UpdateOverlay(&This->IDirectDrawSurface7_iface, src_rect, 03461 dst_impl ? &dst_impl->IDirectDrawSurface7_iface : NULL, dst_rect, flags, fx); 03462 } 03463 03464 static HRESULT WINAPI ddraw_surface1_UpdateOverlay(IDirectDrawSurface *iface, RECT *src_rect, 03465 IDirectDrawSurface *dst_surface, RECT *dst_rect, DWORD flags, DDOVERLAYFX *fx) 03466 { 03467 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface(iface); 03468 IDirectDrawSurfaceImpl *dst_impl = unsafe_impl_from_IDirectDrawSurface(dst_surface); 03469 TRACE("iface %p, src_rect %s, dst_surface %p, dst_rect %s, flags %#x, fx %p.\n", 03470 iface, wine_dbgstr_rect(src_rect), dst_surface, wine_dbgstr_rect(dst_rect), flags, fx); 03471 03472 return ddraw_surface7_UpdateOverlay(&This->IDirectDrawSurface7_iface, src_rect, 03473 dst_impl ? &dst_impl->IDirectDrawSurface7_iface : NULL, dst_rect, flags, fx); 03474 } 03475 03476 /***************************************************************************** 03477 * IDirectDrawSurface7::UpdateOverlayDisplay 03478 * 03479 * The DX7 sdk says that it's not implemented 03480 * 03481 * Params: 03482 * Flags: ? 03483 * 03484 * Returns: DDERR_UNSUPPORTED, because we don't support overlays 03485 * 03486 *****************************************************************************/ 03487 static HRESULT WINAPI ddraw_surface7_UpdateOverlayDisplay(IDirectDrawSurface7 *iface, DWORD Flags) 03488 { 03489 TRACE("iface %p, flags %#x.\n", iface, Flags); 03490 03491 return DDERR_UNSUPPORTED; 03492 } 03493 03494 static HRESULT WINAPI ddraw_surface4_UpdateOverlayDisplay(IDirectDrawSurface4 *iface, DWORD flags) 03495 { 03496 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface4(iface); 03497 TRACE("iface %p, flags %#x.\n", iface, flags); 03498 03499 return ddraw_surface7_UpdateOverlayDisplay(&This->IDirectDrawSurface7_iface, flags); 03500 } 03501 03502 static HRESULT WINAPI ddraw_surface3_UpdateOverlayDisplay(IDirectDrawSurface3 *iface, DWORD flags) 03503 { 03504 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface3(iface); 03505 TRACE("iface %p, flags %#x.\n", iface, flags); 03506 03507 return ddraw_surface7_UpdateOverlayDisplay(&This->IDirectDrawSurface7_iface, flags); 03508 } 03509 03510 static HRESULT WINAPI ddraw_surface2_UpdateOverlayDisplay(IDirectDrawSurface2 *iface, DWORD flags) 03511 { 03512 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface2(iface); 03513 TRACE("iface %p, flags %#x.\n", iface, flags); 03514 03515 return ddraw_surface7_UpdateOverlayDisplay(&This->IDirectDrawSurface7_iface, flags); 03516 } 03517 03518 static HRESULT WINAPI ddraw_surface1_UpdateOverlayDisplay(IDirectDrawSurface *iface, DWORD flags) 03519 { 03520 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface(iface); 03521 TRACE("iface %p, flags %#x.\n", iface, flags); 03522 03523 return ddraw_surface7_UpdateOverlayDisplay(&This->IDirectDrawSurface7_iface, flags); 03524 } 03525 03526 /***************************************************************************** 03527 * IDirectDrawSurface7::UpdateOverlayZOrder 03528 * 03529 * Sets an overlay's Z order 03530 * 03531 * Params: 03532 * Flags: DDOVERZ_* flags 03533 * DDSRef: Defines the relative position in the overlay chain 03534 * 03535 * Returns: 03536 * DDERR_NOTOVERLAYSURFACE, because we don't support overlays 03537 * 03538 *****************************************************************************/ 03539 static HRESULT WINAPI ddraw_surface7_UpdateOverlayZOrder(IDirectDrawSurface7 *iface, 03540 DWORD Flags, IDirectDrawSurface7 *DDSRef) 03541 { 03542 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface7(iface); 03543 IDirectDrawSurfaceImpl *Ref = unsafe_impl_from_IDirectDrawSurface7(DDSRef); 03544 HRESULT hr; 03545 03546 TRACE("iface %p, flags %#x, reference %p.\n", iface, Flags, DDSRef); 03547 03548 wined3d_mutex_lock(); 03549 hr = wined3d_surface_update_overlay_z_order(This->wined3d_surface, 03550 Flags, Ref ? Ref->wined3d_surface : NULL); 03551 wined3d_mutex_unlock(); 03552 03553 return hr; 03554 } 03555 03556 static HRESULT WINAPI ddraw_surface4_UpdateOverlayZOrder(IDirectDrawSurface4 *iface, 03557 DWORD flags, IDirectDrawSurface4 *reference) 03558 { 03559 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface4(iface); 03560 IDirectDrawSurfaceImpl *reference_impl = unsafe_impl_from_IDirectDrawSurface4(reference); 03561 TRACE("iface %p, flags %#x, reference %p.\n", iface, flags, reference); 03562 03563 return ddraw_surface7_UpdateOverlayZOrder(&This->IDirectDrawSurface7_iface, flags, 03564 reference_impl ? &reference_impl->IDirectDrawSurface7_iface : NULL); 03565 } 03566 03567 static HRESULT WINAPI ddraw_surface3_UpdateOverlayZOrder(IDirectDrawSurface3 *iface, 03568 DWORD flags, IDirectDrawSurface3 *reference) 03569 { 03570 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface3(iface); 03571 IDirectDrawSurfaceImpl *reference_impl = unsafe_impl_from_IDirectDrawSurface3(reference); 03572 TRACE("iface %p, flags %#x, reference %p.\n", iface, flags, reference); 03573 03574 return ddraw_surface7_UpdateOverlayZOrder(&This->IDirectDrawSurface7_iface, flags, 03575 reference_impl ? &reference_impl->IDirectDrawSurface7_iface : NULL); 03576 } 03577 03578 static HRESULT WINAPI ddraw_surface2_UpdateOverlayZOrder(IDirectDrawSurface2 *iface, 03579 DWORD flags, IDirectDrawSurface2 *reference) 03580 { 03581 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface2(iface); 03582 IDirectDrawSurfaceImpl *reference_impl = unsafe_impl_from_IDirectDrawSurface2(reference); 03583 TRACE("iface %p, flags %#x, reference %p.\n", iface, flags, reference); 03584 03585 return ddraw_surface7_UpdateOverlayZOrder(&This->IDirectDrawSurface7_iface, flags, 03586 reference_impl ? &reference_impl->IDirectDrawSurface7_iface : NULL); 03587 } 03588 03589 static HRESULT WINAPI ddraw_surface1_UpdateOverlayZOrder(IDirectDrawSurface *iface, 03590 DWORD flags, IDirectDrawSurface *reference) 03591 { 03592 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface(iface); 03593 IDirectDrawSurfaceImpl *reference_impl = unsafe_impl_from_IDirectDrawSurface(reference); 03594 TRACE("iface %p, flags %#x, reference %p.\n", iface, flags, reference); 03595 03596 return ddraw_surface7_UpdateOverlayZOrder(&This->IDirectDrawSurface7_iface, flags, 03597 reference_impl ? &reference_impl->IDirectDrawSurface7_iface : NULL); 03598 } 03599 03600 /***************************************************************************** 03601 * IDirectDrawSurface7::GetDDInterface 03602 * 03603 * Returns the IDirectDraw7 interface pointer of the DirectDraw object this 03604 * surface belongs to 03605 * 03606 * Params: 03607 * DD: Address to write the interface pointer to 03608 * 03609 * Returns: 03610 * DD_OK on success 03611 * DDERR_INVALIDPARAMS if DD is NULL 03612 * 03613 *****************************************************************************/ 03614 static HRESULT WINAPI ddraw_surface7_GetDDInterface(IDirectDrawSurface7 *iface, void **DD) 03615 { 03616 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface7(iface); 03617 03618 TRACE("iface %p, ddraw %p.\n", iface, DD); 03619 03620 if(!DD) 03621 return DDERR_INVALIDPARAMS; 03622 03623 switch(This->version) 03624 { 03625 case 7: 03626 *DD = &This->ddraw->IDirectDraw7_iface; 03627 break; 03628 03629 case 4: 03630 *DD = &This->ddraw->IDirectDraw4_iface; 03631 break; 03632 03633 case 2: 03634 *DD = &This->ddraw->IDirectDraw2_iface; 03635 break; 03636 03637 case 1: 03638 *DD = &This->ddraw->IDirectDraw_iface; 03639 break; 03640 03641 } 03642 IUnknown_AddRef((IUnknown *)*DD); 03643 03644 return DD_OK; 03645 } 03646 03647 static HRESULT WINAPI ddraw_surface4_GetDDInterface(IDirectDrawSurface4 *iface, void **ddraw) 03648 { 03649 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface4(iface); 03650 TRACE("iface %p, ddraw %p.\n", iface, ddraw); 03651 03652 return ddraw_surface7_GetDDInterface(&This->IDirectDrawSurface7_iface, ddraw); 03653 } 03654 03655 static HRESULT WINAPI ddraw_surface3_GetDDInterface(IDirectDrawSurface3 *iface, void **ddraw) 03656 { 03657 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface3(iface); 03658 TRACE("iface %p, ddraw %p.\n", iface, ddraw); 03659 03660 return ddraw_surface7_GetDDInterface(&This->IDirectDrawSurface7_iface, ddraw); 03661 } 03662 03663 static HRESULT WINAPI ddraw_surface2_GetDDInterface(IDirectDrawSurface2 *iface, void **ddraw) 03664 { 03665 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface2(iface); 03666 TRACE("iface %p, ddraw %p.\n", iface, ddraw); 03667 03668 return ddraw_surface7_GetDDInterface(&This->IDirectDrawSurface7_iface, ddraw); 03669 } 03670 03671 /* This seems also windows implementation specific - I don't think WineD3D needs this */ 03672 static HRESULT WINAPI ddraw_surface7_ChangeUniquenessValue(IDirectDrawSurface7 *iface) 03673 { 03674 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface7(iface); 03675 volatile IDirectDrawSurfaceImpl* vThis = This; 03676 03677 TRACE("iface %p.\n", iface); 03678 03679 wined3d_mutex_lock(); 03680 /* A uniqueness value of 0 is apparently special. 03681 * This needs to be checked. 03682 * TODO: Write tests for this code and check if the volatile, interlocked stuff is really needed 03683 */ 03684 while (1) { 03685 DWORD old_uniqueness_value = vThis->uniqueness_value; 03686 DWORD new_uniqueness_value = old_uniqueness_value+1; 03687 03688 if (old_uniqueness_value == 0) break; 03689 if (new_uniqueness_value == 0) new_uniqueness_value = 1; 03690 03691 if (InterlockedCompareExchange((LONG*)&vThis->uniqueness_value, 03692 old_uniqueness_value, 03693 new_uniqueness_value) 03694 == old_uniqueness_value) 03695 break; 03696 } 03697 03698 wined3d_mutex_unlock(); 03699 03700 return DD_OK; 03701 } 03702 03703 static HRESULT WINAPI ddraw_surface4_ChangeUniquenessValue(IDirectDrawSurface4 *iface) 03704 { 03705 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface4(iface); 03706 TRACE("iface %p.\n", iface); 03707 03708 return ddraw_surface7_ChangeUniquenessValue(&This->IDirectDrawSurface7_iface); 03709 } 03710 03711 static HRESULT WINAPI ddraw_surface7_GetUniquenessValue(IDirectDrawSurface7 *iface, DWORD *pValue) 03712 { 03713 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface7(iface); 03714 03715 TRACE("iface %p, value %p.\n", iface, pValue); 03716 03717 wined3d_mutex_lock(); 03718 *pValue = This->uniqueness_value; 03719 wined3d_mutex_unlock(); 03720 03721 return DD_OK; 03722 } 03723 03724 static HRESULT WINAPI ddraw_surface4_GetUniquenessValue(IDirectDrawSurface4 *iface, DWORD *pValue) 03725 { 03726 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface4(iface); 03727 TRACE("iface %p, value %p.\n", iface, pValue); 03728 03729 return ddraw_surface7_GetUniquenessValue(&This->IDirectDrawSurface7_iface, pValue); 03730 } 03731 03732 /***************************************************************************** 03733 * IDirectDrawSurface7::SetLOD 03734 * 03735 * Sets the level of detail of a texture 03736 * 03737 * Params: 03738 * MaxLOD: LOD to set 03739 * 03740 * Returns: 03741 * DD_OK on success 03742 * DDERR_INVALIDOBJECT if the surface is invalid for this method 03743 * 03744 *****************************************************************************/ 03745 static HRESULT WINAPI ddraw_surface7_SetLOD(IDirectDrawSurface7 *iface, DWORD MaxLOD) 03746 { 03747 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface7(iface); 03748 HRESULT hr; 03749 03750 TRACE("iface %p, lod %u.\n", iface, MaxLOD); 03751 03752 wined3d_mutex_lock(); 03753 if (!(This->surface_desc.ddsCaps.dwCaps2 & DDSCAPS2_TEXTUREMANAGE)) 03754 { 03755 wined3d_mutex_unlock(); 03756 return DDERR_INVALIDOBJECT; 03757 } 03758 03759 if (!This->wined3d_texture) 03760 { 03761 ERR("(%p) The DirectDraw texture has no WineD3DTexture!\n", This); 03762 wined3d_mutex_unlock(); 03763 return DDERR_INVALIDOBJECT; 03764 } 03765 03766 hr = wined3d_texture_set_lod(This->wined3d_texture, MaxLOD); 03767 wined3d_mutex_unlock(); 03768 03769 return hr; 03770 } 03771 03772 /***************************************************************************** 03773 * IDirectDrawSurface7::GetLOD 03774 * 03775 * Returns the level of detail of a Direct3D texture 03776 * 03777 * Params: 03778 * MaxLOD: Address to write the LOD to 03779 * 03780 * Returns: 03781 * DD_OK on success 03782 * DDERR_INVALIDPARAMS if MaxLOD is NULL 03783 * DDERR_INVALIDOBJECT if the surface is invalid for this method 03784 * 03785 *****************************************************************************/ 03786 static HRESULT WINAPI ddraw_surface7_GetLOD(IDirectDrawSurface7 *iface, DWORD *MaxLOD) 03787 { 03788 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface7(iface); 03789 03790 TRACE("iface %p, lod %p.\n", iface, MaxLOD); 03791 03792 if(!MaxLOD) 03793 return DDERR_INVALIDPARAMS; 03794 03795 wined3d_mutex_lock(); 03796 if (!(This->surface_desc.ddsCaps.dwCaps2 & DDSCAPS2_TEXTUREMANAGE)) 03797 { 03798 wined3d_mutex_unlock(); 03799 return DDERR_INVALIDOBJECT; 03800 } 03801 03802 *MaxLOD = wined3d_texture_get_lod(This->wined3d_texture); 03803 wined3d_mutex_unlock(); 03804 03805 return DD_OK; 03806 } 03807 03808 /***************************************************************************** 03809 * IDirectDrawSurface7::BltFast 03810 * 03811 * Performs a fast Blit. 03812 * 03813 * Params: 03814 * dstx: The x coordinate to blit to on the destination 03815 * dsty: The y coordinate to blit to on the destination 03816 * Source: The source surface 03817 * rsrc: The source rectangle 03818 * trans: Type of transfer. Some DDBLTFAST_* flags 03819 * 03820 * Returns: 03821 * DD_OK on success 03822 * For more details, see IWineD3DSurface::BltFast 03823 * 03824 *****************************************************************************/ 03825 static HRESULT WINAPI ddraw_surface7_BltFast(IDirectDrawSurface7 *iface, DWORD dstx, DWORD dsty, 03826 IDirectDrawSurface7 *Source, RECT *rsrc, DWORD trans) 03827 { 03828 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface7(iface); 03829 IDirectDrawSurfaceImpl *src = unsafe_impl_from_IDirectDrawSurface7(Source); 03830 DWORD src_w, src_h, dst_w, dst_h; 03831 HRESULT hr = DD_OK; 03832 DWORD flags = 0; 03833 RECT dst_rect; 03834 03835 TRACE("iface %p, dst_x %u, dst_y %u, src_surface %p, src_rect %s, flags %#x.\n", 03836 iface, dstx, dsty, Source, wine_dbgstr_rect(rsrc), trans); 03837 03838 dst_w = This->surface_desc.dwWidth; 03839 dst_h = This->surface_desc.dwHeight; 03840 03841 /* Source must be != NULL, This is not checked by windows. Windows happily throws a 0xc0000005 03842 * in that case 03843 */ 03844 if(rsrc) 03845 { 03846 src_w = rsrc->right - rsrc->left; 03847 src_h = rsrc->bottom - rsrc->top; 03848 } 03849 else 03850 { 03851 src_w = src->surface_desc.dwWidth; 03852 src_h = src->surface_desc.dwHeight; 03853 } 03854 03855 if (src_w > dst_w || dstx > dst_w - src_w 03856 || src_h > dst_h || dsty > dst_h - src_h) 03857 { 03858 WARN("Destination area out of bounds, returning DDERR_INVALIDRECT.\n"); 03859 return DDERR_INVALIDRECT; 03860 } 03861 03862 SetRect(&dst_rect, dstx, dsty, dstx + src_w, dsty + src_h); 03863 if (trans & DDBLTFAST_SRCCOLORKEY) 03864 flags |= WINEDDBLT_KEYSRC; 03865 if (trans & DDBLTFAST_DESTCOLORKEY) 03866 flags |= WINEDDBLT_KEYDEST; 03867 if (trans & DDBLTFAST_WAIT) 03868 flags |= WINEDDBLT_WAIT; 03869 if (trans & DDBLTFAST_DONOTWAIT) 03870 flags |= WINEDDBLT_DONOTWAIT; 03871 03872 wined3d_mutex_lock(); 03873 if (This->clipper) 03874 { 03875 wined3d_mutex_unlock(); 03876 WARN("Destination surface has a clipper set, returning DDERR_BLTFASTCANTCLIP.\n"); 03877 return DDERR_BLTFASTCANTCLIP; 03878 } 03879 03880 if (src->surface_desc.ddsCaps.dwCaps & DDSCAPS_FRONTBUFFER) 03881 hr = ddraw_surface_update_frontbuffer(src, rsrc, TRUE); 03882 if (SUCCEEDED(hr)) 03883 hr = wined3d_surface_blt(This->wined3d_surface, &dst_rect, 03884 src->wined3d_surface, rsrc, flags, NULL, WINED3D_TEXF_POINT); 03885 if (SUCCEEDED(hr) && (This->surface_desc.ddsCaps.dwCaps & DDSCAPS_FRONTBUFFER)) 03886 hr = ddraw_surface_update_frontbuffer(This, &dst_rect, FALSE); 03887 wined3d_mutex_unlock(); 03888 03889 switch(hr) 03890 { 03891 case WINED3DERR_NOTAVAILABLE: return DDERR_UNSUPPORTED; 03892 case WINED3DERR_WRONGTEXTUREFORMAT: return DDERR_INVALIDPIXELFORMAT; 03893 default: return hr; 03894 } 03895 } 03896 03897 static HRESULT WINAPI ddraw_surface4_BltFast(IDirectDrawSurface4 *iface, DWORD dst_x, DWORD dst_y, 03898 IDirectDrawSurface4 *src_surface, RECT *src_rect, DWORD flags) 03899 { 03900 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface4(iface); 03901 IDirectDrawSurfaceImpl *src_impl = unsafe_impl_from_IDirectDrawSurface4(src_surface); 03902 TRACE("iface %p, dst_x %u, dst_y %u, src_surface %p, src_rect %s, flags %#x.\n", 03903 iface, dst_x, dst_y, src_surface, wine_dbgstr_rect(src_rect), flags); 03904 03905 return ddraw_surface7_BltFast(&This->IDirectDrawSurface7_iface, dst_x, dst_y, 03906 src_impl ? &src_impl->IDirectDrawSurface7_iface : NULL, src_rect, flags); 03907 } 03908 03909 static HRESULT WINAPI ddraw_surface3_BltFast(IDirectDrawSurface3 *iface, DWORD dst_x, DWORD dst_y, 03910 IDirectDrawSurface3 *src_surface, RECT *src_rect, DWORD flags) 03911 { 03912 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface3(iface); 03913 IDirectDrawSurfaceImpl *src_impl = unsafe_impl_from_IDirectDrawSurface3(src_surface); 03914 TRACE("iface %p, dst_x %u, dst_y %u, src_surface %p, src_rect %s, flags %#x.\n", 03915 iface, dst_x, dst_y, src_surface, wine_dbgstr_rect(src_rect), flags); 03916 03917 return ddraw_surface7_BltFast(&This->IDirectDrawSurface7_iface, dst_x, dst_y, 03918 src_impl ? &src_impl->IDirectDrawSurface7_iface : NULL, src_rect, flags); 03919 } 03920 03921 static HRESULT WINAPI ddraw_surface2_BltFast(IDirectDrawSurface2 *iface, DWORD dst_x, DWORD dst_y, 03922 IDirectDrawSurface2 *src_surface, RECT *src_rect, DWORD flags) 03923 { 03924 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface2(iface); 03925 IDirectDrawSurfaceImpl *src_impl = unsafe_impl_from_IDirectDrawSurface2(src_surface); 03926 TRACE("iface %p, dst_x %u, dst_y %u, src_surface %p, src_rect %s, flags %#x.\n", 03927 iface, dst_x, dst_y, src_surface, wine_dbgstr_rect(src_rect), flags); 03928 03929 return ddraw_surface7_BltFast(&This->IDirectDrawSurface7_iface, dst_x, dst_y, 03930 src_impl ? &src_impl->IDirectDrawSurface7_iface : NULL, src_rect, flags); 03931 } 03932 03933 static HRESULT WINAPI ddraw_surface1_BltFast(IDirectDrawSurface *iface, DWORD dst_x, DWORD dst_y, 03934 IDirectDrawSurface *src_surface, RECT *src_rect, DWORD flags) 03935 { 03936 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface(iface); 03937 IDirectDrawSurfaceImpl *src_impl = unsafe_impl_from_IDirectDrawSurface(src_surface); 03938 TRACE("iface %p, dst_x %u, dst_y %u, src_surface %p, src_rect %s, flags %#x.\n", 03939 iface, dst_x, dst_y, src_surface, wine_dbgstr_rect(src_rect), flags); 03940 03941 return ddraw_surface7_BltFast(&This->IDirectDrawSurface7_iface, dst_x, dst_y, 03942 src_impl ? &src_impl->IDirectDrawSurface7_iface : NULL, src_rect, flags); 03943 } 03944 03945 /***************************************************************************** 03946 * IDirectDrawSurface7::GetClipper 03947 * 03948 * Returns the IDirectDrawClipper interface of the clipper assigned to this 03949 * surface 03950 * 03951 * Params: 03952 * Clipper: Address to store the interface pointer at 03953 * 03954 * Returns: 03955 * DD_OK on success 03956 * DDERR_INVALIDPARAMS if Clipper is NULL 03957 * DDERR_NOCLIPPERATTACHED if there's no clipper attached 03958 * 03959 *****************************************************************************/ 03960 static HRESULT WINAPI ddraw_surface7_GetClipper(IDirectDrawSurface7 *iface, IDirectDrawClipper **Clipper) 03961 { 03962 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface7(iface); 03963 03964 TRACE("iface %p, clipper %p.\n", iface, Clipper); 03965 03966 if (!Clipper) 03967 return DDERR_INVALIDPARAMS; 03968 03969 wined3d_mutex_lock(); 03970 if(This->clipper == NULL) 03971 { 03972 wined3d_mutex_unlock(); 03973 return DDERR_NOCLIPPERATTACHED; 03974 } 03975 03976 *Clipper = (IDirectDrawClipper *)This->clipper; 03977 IDirectDrawClipper_AddRef(*Clipper); 03978 wined3d_mutex_unlock(); 03979 03980 return DD_OK; 03981 } 03982 03983 static HRESULT WINAPI ddraw_surface4_GetClipper(IDirectDrawSurface4 *iface, IDirectDrawClipper **clipper) 03984 { 03985 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface4(iface); 03986 TRACE("iface %p, clipper %p.\n", iface, clipper); 03987 03988 return ddraw_surface7_GetClipper(&This->IDirectDrawSurface7_iface, clipper); 03989 } 03990 03991 static HRESULT WINAPI ddraw_surface3_GetClipper(IDirectDrawSurface3 *iface, IDirectDrawClipper **clipper) 03992 { 03993 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface3(iface); 03994 TRACE("iface %p, clipper %p.\n", iface, clipper); 03995 03996 return ddraw_surface7_GetClipper(&This->IDirectDrawSurface7_iface, clipper); 03997 } 03998 03999 static HRESULT WINAPI ddraw_surface2_GetClipper(IDirectDrawSurface2 *iface, IDirectDrawClipper **clipper) 04000 { 04001 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface2(iface); 04002 TRACE("iface %p, clipper %p.\n", iface, clipper); 04003 04004 return ddraw_surface7_GetClipper(&This->IDirectDrawSurface7_iface, clipper); 04005 } 04006 04007 static HRESULT WINAPI ddraw_surface1_GetClipper(IDirectDrawSurface *iface, IDirectDrawClipper **clipper) 04008 { 04009 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface(iface); 04010 TRACE("iface %p, clipper %p.\n", iface, clipper); 04011 04012 return ddraw_surface7_GetClipper(&This->IDirectDrawSurface7_iface, clipper); 04013 } 04014 04015 /***************************************************************************** 04016 * IDirectDrawSurface7::SetClipper 04017 * 04018 * Sets a clipper for the surface 04019 * 04020 * Params: 04021 * Clipper: IDirectDrawClipper interface of the clipper to set 04022 * 04023 * Returns: 04024 * DD_OK on success 04025 * 04026 *****************************************************************************/ 04027 static HRESULT WINAPI ddraw_surface7_SetClipper(IDirectDrawSurface7 *iface, 04028 IDirectDrawClipper *iclipper) 04029 { 04030 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface7(iface); 04031 struct ddraw_clipper *clipper = unsafe_impl_from_IDirectDrawClipper(iclipper); 04032 struct ddraw_clipper *old_clipper = This->clipper; 04033 HWND clipWindow; 04034 04035 TRACE("iface %p, clipper %p.\n", iface, iclipper); 04036 04037 wined3d_mutex_lock(); 04038 if (clipper == This->clipper) 04039 { 04040 wined3d_mutex_unlock(); 04041 return DD_OK; 04042 } 04043 04044 This->clipper = clipper; 04045 04046 if (clipper != NULL) 04047 IDirectDrawClipper_AddRef(iclipper); 04048 if (old_clipper) 04049 IDirectDrawClipper_Release(&old_clipper->IDirectDrawClipper_iface); 04050 04051 if ((This->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) && This->ddraw->wined3d_swapchain) 04052 { 04053 clipWindow = NULL; 04054 if(clipper) { 04055 IDirectDrawClipper_GetHWnd(iclipper, &clipWindow); 04056 } 04057 04058 if (clipWindow) 04059 { 04060 wined3d_swapchain_set_window(This->ddraw->wined3d_swapchain, clipWindow); 04061 ddraw_set_swapchain_window(This->ddraw, clipWindow); 04062 } 04063 else 04064 { 04065 wined3d_swapchain_set_window(This->ddraw->wined3d_swapchain, This->ddraw->d3d_window); 04066 ddraw_set_swapchain_window(This->ddraw, This->ddraw->dest_window); 04067 } 04068 } 04069 04070 wined3d_mutex_unlock(); 04071 04072 return DD_OK; 04073 } 04074 04075 static HRESULT WINAPI ddraw_surface4_SetClipper(IDirectDrawSurface4 *iface, IDirectDrawClipper *clipper) 04076 { 04077 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface4(iface); 04078 TRACE("iface %p, clipper %p.\n", iface, clipper); 04079 04080 return ddraw_surface7_SetClipper(&This->IDirectDrawSurface7_iface, clipper); 04081 } 04082 04083 static HRESULT WINAPI ddraw_surface3_SetClipper(IDirectDrawSurface3 *iface, IDirectDrawClipper *clipper) 04084 { 04085 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface3(iface); 04086 TRACE("iface %p, clipper %p.\n", iface, clipper); 04087 04088 return ddraw_surface7_SetClipper(&This->IDirectDrawSurface7_iface, clipper); 04089 } 04090 04091 static HRESULT WINAPI ddraw_surface2_SetClipper(IDirectDrawSurface2 *iface, IDirectDrawClipper *clipper) 04092 { 04093 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface2(iface); 04094 TRACE("iface %p, clipper %p.\n", iface, clipper); 04095 04096 return ddraw_surface7_SetClipper(&This->IDirectDrawSurface7_iface, clipper); 04097 } 04098 04099 static HRESULT WINAPI ddraw_surface1_SetClipper(IDirectDrawSurface *iface, IDirectDrawClipper *clipper) 04100 { 04101 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface(iface); 04102 TRACE("iface %p, clipper %p.\n", iface, clipper); 04103 04104 return ddraw_surface7_SetClipper(&This->IDirectDrawSurface7_iface, clipper); 04105 } 04106 04107 /***************************************************************************** 04108 * IDirectDrawSurface7::SetSurfaceDesc 04109 * 04110 * Sets the surface description. It can override the pixel format, the surface 04111 * memory, ... 04112 * It's not really tested. 04113 * 04114 * Params: 04115 * DDSD: Pointer to the new surface description to set 04116 * Flags: Some flags 04117 * 04118 * Returns: 04119 * DD_OK on success 04120 * DDERR_INVALIDPARAMS if DDSD is NULL 04121 * 04122 *****************************************************************************/ 04123 static HRESULT WINAPI ddraw_surface7_SetSurfaceDesc(IDirectDrawSurface7 *iface, DDSURFACEDESC2 *DDSD, DWORD Flags) 04124 { 04125 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface7(iface); 04126 HRESULT hr; 04127 const DWORD allowed_flags = DDSD_LPSURFACE | DDSD_PIXELFORMAT | DDSD_WIDTH 04128 | DDSD_HEIGHT | DDSD_PITCH | DDSD_CAPS; 04129 enum wined3d_format_id format_id; 04130 BOOL update_wined3d = FALSE; 04131 UINT width, height; 04132 04133 TRACE("iface %p, surface_desc %p, flags %#x.\n", iface, DDSD, Flags); 04134 04135 if (!DDSD) 04136 { 04137 WARN("DDSD is NULL, returning DDERR_INVALIDPARAMS\n"); 04138 return DDERR_INVALIDPARAMS; 04139 } 04140 if (Flags) 04141 { 04142 WARN("Flags is %x, returning DDERR_INVALIDPARAMS\n", Flags); 04143 return DDERR_INVALIDPARAMS; 04144 } 04145 if (!(This->surface_desc.ddsCaps.dwCaps & DDSCAPS_SYSTEMMEMORY)) 04146 { 04147 WARN("Surface is not in system memory, returning DDERR_INVALIDSURFACETYPE.\n"); 04148 return DDERR_INVALIDSURFACETYPE; 04149 } 04150 04151 /* Tests show that only LPSURFACE and PIXELFORMAT can be set, and LPSURFACE is required 04152 * for PIXELFORMAT to work */ 04153 if (DDSD->dwFlags & ~allowed_flags) 04154 { 04155 WARN("Invalid flags (0x%08x) set, returning DDERR_INVALIDPARAMS\n", DDSD->dwFlags); 04156 return DDERR_INVALIDPARAMS; 04157 } 04158 if (!(DDSD->dwFlags & DDSD_LPSURFACE)) 04159 { 04160 WARN("DDSD_LPSURFACE is not set, returning DDERR_INVALIDPARAMS\n"); 04161 return DDERR_INVALIDPARAMS; 04162 } 04163 if (DDSD->dwFlags & DDSD_CAPS) 04164 { 04165 WARN("DDSD_CAPS is set, returning DDERR_INVALIDCAPS.\n"); 04166 return DDERR_INVALIDCAPS; 04167 } 04168 if (DDSD->dwFlags & DDSD_WIDTH) 04169 { 04170 if (!(DDSD->dwFlags & DDSD_PITCH)) 04171 { 04172 WARN("DDSD_WIDTH is set, but DDSD_PITCH is not, returning DDERR_INVALIDPARAMS.\n"); 04173 return DDERR_INVALIDPARAMS; 04174 } 04175 if (!DDSD->dwWidth || DDSD->u1.lPitch <= 0 || DDSD->u1.lPitch & 0x3) 04176 { 04177 WARN("Pitch is %d, width is %u, returning DDERR_INVALIDPARAMS.\n", 04178 DDSD->u1.lPitch, DDSD->dwWidth); 04179 return DDERR_INVALIDPARAMS; 04180 } 04181 if (DDSD->dwWidth != This->surface_desc.dwWidth) 04182 { 04183 TRACE("Surface width changed from %u to %u.\n", This->surface_desc.dwWidth, DDSD->dwWidth); 04184 update_wined3d = TRUE; 04185 } 04186 if (DDSD->u1.lPitch != This->surface_desc.u1.lPitch) 04187 { 04188 TRACE("Surface pitch changed from %u to %u.\n", This->surface_desc.u1.lPitch, DDSD->u1.lPitch); 04189 update_wined3d = TRUE; 04190 } 04191 width = DDSD->dwWidth; 04192 } 04193 else if (DDSD->dwFlags & DDSD_PITCH) 04194 { 04195 WARN("DDSD_PITCH is set, but DDSD_WIDTH is not, returning DDERR_INVALIDPARAMS.\n"); 04196 return DDERR_INVALIDPARAMS; 04197 } 04198 else 04199 { 04200 width = This->surface_desc.dwWidth; 04201 } 04202 04203 if (DDSD->dwFlags & DDSD_HEIGHT) 04204 { 04205 if (!DDSD->dwHeight) 04206 { 04207 WARN("Height is 0, returning DDERR_INVALIDPARAMS.\n"); 04208 return DDERR_INVALIDPARAMS; 04209 } 04210 if (DDSD->dwHeight != This->surface_desc.dwHeight) 04211 { 04212 TRACE("Surface height changed from %u to %u.\n", This->surface_desc.dwHeight, DDSD->dwHeight); 04213 update_wined3d = TRUE; 04214 } 04215 height = DDSD->dwHeight; 04216 } 04217 else 04218 { 04219 height = This->surface_desc.dwHeight; 04220 } 04221 04222 wined3d_mutex_lock(); 04223 if (DDSD->dwFlags & DDSD_PIXELFORMAT) 04224 { 04225 enum wined3d_format_id current_format_id; 04226 format_id = PixelFormat_DD2WineD3D(&DDSD->u4.ddpfPixelFormat); 04227 04228 if (format_id == WINED3DFMT_UNKNOWN) 04229 { 04230 ERR("Requested to set an unknown pixelformat\n"); 04231 wined3d_mutex_unlock(); 04232 return DDERR_INVALIDPARAMS; 04233 } 04234 current_format_id = PixelFormat_DD2WineD3D(&This->surface_desc.u4.ddpfPixelFormat); 04235 if (format_id != current_format_id) 04236 { 04237 TRACE("Surface format changed from %#x to %#x.\n", current_format_id, format_id); 04238 update_wined3d = TRUE; 04239 } 04240 } 04241 else 04242 { 04243 format_id = PixelFormat_DD2WineD3D(&This->surface_desc.u4.ddpfPixelFormat); 04244 } 04245 04246 if (update_wined3d) 04247 { 04248 if (FAILED(hr = wined3d_surface_update_desc(This->wined3d_surface, width, height, 04249 format_id, WINED3D_MULTISAMPLE_NONE, 0))) 04250 { 04251 WARN("Failed to update surface desc, hr %#x.\n", hr); 04252 wined3d_mutex_unlock(); 04253 return hr; 04254 } 04255 04256 if (DDSD->dwFlags & DDSD_WIDTH) 04257 This->surface_desc.dwWidth = width; 04258 if (DDSD->dwFlags & DDSD_PITCH) 04259 This->surface_desc.u1.lPitch = DDSD->u1.lPitch; 04260 if (DDSD->dwFlags & DDSD_HEIGHT) 04261 This->surface_desc.dwHeight = height; 04262 if (DDSD->dwFlags & DDSD_PIXELFORMAT) 04263 This->surface_desc.u4.ddpfPixelFormat = DDSD->u4.ddpfPixelFormat; 04264 } 04265 04266 if (DDSD->dwFlags & DDSD_LPSURFACE && DDSD->lpSurface) 04267 { 04268 hr = wined3d_surface_set_mem(This->wined3d_surface, DDSD->lpSurface); 04269 if (FAILED(hr)) 04270 { 04271 /* No need for a trace here, wined3d does that for us */ 04272 switch(hr) 04273 { 04274 case WINED3DERR_INVALIDCALL: 04275 wined3d_mutex_unlock(); 04276 return DDERR_INVALIDPARAMS; 04277 default: 04278 break; /* Go on */ 04279 } 04280 } 04281 /* DDSD->lpSurface is set by Lock() */ 04282 } 04283 04284 wined3d_mutex_unlock(); 04285 04286 return DD_OK; 04287 } 04288 04289 static HRESULT WINAPI ddraw_surface4_SetSurfaceDesc(IDirectDrawSurface4 *iface, 04290 DDSURFACEDESC2 *surface_desc, DWORD flags) 04291 { 04292 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface4(iface); 04293 TRACE("iface %p, surface_desc %p, flags %#x.\n", iface, surface_desc, flags); 04294 04295 return ddraw_surface7_SetSurfaceDesc(&This->IDirectDrawSurface7_iface, 04296 surface_desc, flags); 04297 } 04298 04299 static HRESULT WINAPI ddraw_surface3_SetSurfaceDesc(IDirectDrawSurface3 *iface, 04300 DDSURFACEDESC *surface_desc, DWORD flags) 04301 { 04302 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface3(iface); 04303 DDSURFACEDESC2 surface_desc2; 04304 TRACE("iface %p, surface_desc %p, flags %#x.\n", iface, surface_desc, flags); 04305 04306 if (surface_desc) DDSD_to_DDSD2(surface_desc, &surface_desc2); 04307 return ddraw_surface7_SetSurfaceDesc(&This->IDirectDrawSurface7_iface, 04308 surface_desc ? &surface_desc2 : NULL, flags); 04309 } 04310 04311 /***************************************************************************** 04312 * IDirectDrawSurface7::GetPalette 04313 * 04314 * Returns the IDirectDrawPalette interface of the palette currently assigned 04315 * to the surface 04316 * 04317 * Params: 04318 * Pal: Address to write the interface pointer to 04319 * 04320 * Returns: 04321 * DD_OK on success 04322 * DDERR_INVALIDPARAMS if Pal is NULL 04323 * 04324 *****************************************************************************/ 04325 static HRESULT WINAPI ddraw_surface7_GetPalette(IDirectDrawSurface7 *iface, IDirectDrawPalette **Pal) 04326 { 04327 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface7(iface); 04328 struct wined3d_palette *wined3d_palette; 04329 HRESULT hr = DD_OK; 04330 04331 TRACE("iface %p, palette %p.\n", iface, Pal); 04332 04333 if(!Pal) 04334 return DDERR_INVALIDPARAMS; 04335 04336 wined3d_mutex_lock(); 04337 wined3d_palette = wined3d_surface_get_palette(This->wined3d_surface); 04338 if (wined3d_palette) 04339 { 04340 *Pal = wined3d_palette_get_parent(wined3d_palette); 04341 IDirectDrawPalette_AddRef(*Pal); 04342 } 04343 else 04344 { 04345 *Pal = NULL; 04346 hr = DDERR_NOPALETTEATTACHED; 04347 } 04348 04349 wined3d_mutex_unlock(); 04350 04351 return hr; 04352 } 04353 04354 static HRESULT WINAPI ddraw_surface4_GetPalette(IDirectDrawSurface4 *iface, IDirectDrawPalette **palette) 04355 { 04356 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface4(iface); 04357 TRACE("iface %p, palette %p.\n", iface, palette); 04358 04359 return ddraw_surface7_GetPalette(&This->IDirectDrawSurface7_iface, palette); 04360 } 04361 04362 static HRESULT WINAPI ddraw_surface3_GetPalette(IDirectDrawSurface3 *iface, IDirectDrawPalette **palette) 04363 { 04364 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface3(iface); 04365 TRACE("iface %p, palette %p.\n", iface, palette); 04366 04367 return ddraw_surface7_GetPalette(&This->IDirectDrawSurface7_iface, palette); 04368 } 04369 04370 static HRESULT WINAPI ddraw_surface2_GetPalette(IDirectDrawSurface2 *iface, IDirectDrawPalette **palette) 04371 { 04372 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface2(iface); 04373 TRACE("iface %p, palette %p.\n", iface, palette); 04374 04375 return ddraw_surface7_GetPalette(&This->IDirectDrawSurface7_iface, palette); 04376 } 04377 04378 static HRESULT WINAPI ddraw_surface1_GetPalette(IDirectDrawSurface *iface, IDirectDrawPalette **palette) 04379 { 04380 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface(iface); 04381 TRACE("iface %p, palette %p.\n", iface, palette); 04382 04383 return ddraw_surface7_GetPalette(&This->IDirectDrawSurface7_iface, palette); 04384 } 04385 04386 /***************************************************************************** 04387 * SetColorKeyEnum 04388 * 04389 * EnumAttachedSurface callback for SetColorKey. Used to set color keys 04390 * recursively in the surface tree 04391 * 04392 *****************************************************************************/ 04393 struct SCKContext 04394 { 04395 HRESULT ret; 04396 struct wined3d_color_key *color_key; 04397 DWORD Flags; 04398 }; 04399 04400 static HRESULT WINAPI 04401 SetColorKeyEnum(IDirectDrawSurface7 *surface, 04402 DDSURFACEDESC2 *desc, 04403 void *context) 04404 { 04405 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface7(surface); 04406 struct SCKContext *ctx = context; 04407 HRESULT hr; 04408 04409 hr = wined3d_surface_set_color_key(This->wined3d_surface, ctx->Flags, ctx->color_key); 04410 if (FAILED(hr)) 04411 { 04412 WARN("IWineD3DSurface_SetColorKey failed, hr = %08x\n", hr); 04413 ctx->ret = hr; 04414 } 04415 04416 ddraw_surface7_EnumAttachedSurfaces(surface, context, SetColorKeyEnum); 04417 ddraw_surface7_Release(surface); 04418 04419 return DDENUMRET_OK; 04420 } 04421 04422 /***************************************************************************** 04423 * IDirectDrawSurface7::SetColorKey 04424 * 04425 * Sets the color keying options for the surface. Observations showed that 04426 * in case of complex surfaces the color key has to be assigned to all 04427 * sublevels. 04428 * 04429 * Params: 04430 * Flags: DDCKEY_* 04431 * CKey: The new color key 04432 * 04433 * Returns: 04434 * DD_OK on success 04435 * See IWineD3DSurface::SetColorKey for details 04436 * 04437 *****************************************************************************/ 04438 static HRESULT WINAPI ddraw_surface7_SetColorKey(IDirectDrawSurface7 *iface, DWORD Flags, DDCOLORKEY *CKey) 04439 { 04440 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface7(iface); 04441 DDCOLORKEY FixedCKey; 04442 struct SCKContext ctx = { DD_OK, (struct wined3d_color_key *)(CKey ? &FixedCKey : NULL), Flags }; 04443 04444 TRACE("iface %p, flags %#x, color_key %p.\n", iface, Flags, CKey); 04445 04446 wined3d_mutex_lock(); 04447 if (CKey) 04448 { 04449 FixedCKey = *CKey; 04450 /* Handle case where dwColorSpaceHighValue < dwColorSpaceLowValue */ 04451 if (FixedCKey.dwColorSpaceHighValue < FixedCKey.dwColorSpaceLowValue) 04452 FixedCKey.dwColorSpaceHighValue = FixedCKey.dwColorSpaceLowValue; 04453 04454 switch (Flags & ~DDCKEY_COLORSPACE) 04455 { 04456 case DDCKEY_DESTBLT: 04457 This->surface_desc.ddckCKDestBlt = FixedCKey; 04458 This->surface_desc.dwFlags |= DDSD_CKDESTBLT; 04459 break; 04460 04461 case DDCKEY_DESTOVERLAY: 04462 This->surface_desc.u3.ddckCKDestOverlay = FixedCKey; 04463 This->surface_desc.dwFlags |= DDSD_CKDESTOVERLAY; 04464 break; 04465 04466 case DDCKEY_SRCOVERLAY: 04467 This->surface_desc.ddckCKSrcOverlay = FixedCKey; 04468 This->surface_desc.dwFlags |= DDSD_CKSRCOVERLAY; 04469 break; 04470 04471 case DDCKEY_SRCBLT: 04472 This->surface_desc.ddckCKSrcBlt = FixedCKey; 04473 This->surface_desc.dwFlags |= DDSD_CKSRCBLT; 04474 break; 04475 04476 default: 04477 wined3d_mutex_unlock(); 04478 return DDERR_INVALIDPARAMS; 04479 } 04480 } 04481 else 04482 { 04483 switch (Flags & ~DDCKEY_COLORSPACE) 04484 { 04485 case DDCKEY_DESTBLT: 04486 This->surface_desc.dwFlags &= ~DDSD_CKDESTBLT; 04487 break; 04488 04489 case DDCKEY_DESTOVERLAY: 04490 This->surface_desc.dwFlags &= ~DDSD_CKDESTOVERLAY; 04491 break; 04492 04493 case DDCKEY_SRCOVERLAY: 04494 This->surface_desc.dwFlags &= ~DDSD_CKSRCOVERLAY; 04495 break; 04496 04497 case DDCKEY_SRCBLT: 04498 This->surface_desc.dwFlags &= ~DDSD_CKSRCBLT; 04499 break; 04500 04501 default: 04502 wined3d_mutex_unlock(); 04503 return DDERR_INVALIDPARAMS; 04504 } 04505 } 04506 ctx.ret = wined3d_surface_set_color_key(This->wined3d_surface, Flags, ctx.color_key); 04507 ddraw_surface7_EnumAttachedSurfaces(iface, &ctx, SetColorKeyEnum); 04508 wined3d_mutex_unlock(); 04509 04510 switch(ctx.ret) 04511 { 04512 case WINED3DERR_INVALIDCALL: return DDERR_INVALIDPARAMS; 04513 default: return ctx.ret; 04514 } 04515 } 04516 04517 static HRESULT WINAPI ddraw_surface4_SetColorKey(IDirectDrawSurface4 *iface, DWORD flags, DDCOLORKEY *color_key) 04518 { 04519 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface4(iface); 04520 TRACE("iface %p, flags %#x, color_key %p.\n", iface, flags, color_key); 04521 04522 return ddraw_surface7_SetColorKey(&This->IDirectDrawSurface7_iface, flags, color_key); 04523 } 04524 04525 static HRESULT WINAPI ddraw_surface3_SetColorKey(IDirectDrawSurface3 *iface, DWORD flags, DDCOLORKEY *color_key) 04526 { 04527 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface3(iface); 04528 TRACE("iface %p, flags %#x, color_key %p.\n", iface, flags, color_key); 04529 04530 return ddraw_surface7_SetColorKey(&This->IDirectDrawSurface7_iface, flags, color_key); 04531 } 04532 04533 static HRESULT WINAPI ddraw_surface2_SetColorKey(IDirectDrawSurface2 *iface, DWORD flags, DDCOLORKEY *color_key) 04534 { 04535 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface2(iface); 04536 TRACE("iface %p, flags %#x, color_key %p.\n", iface, flags, color_key); 04537 04538 return ddraw_surface7_SetColorKey(&This->IDirectDrawSurface7_iface, flags, color_key); 04539 } 04540 04541 static HRESULT WINAPI ddraw_surface1_SetColorKey(IDirectDrawSurface *iface, DWORD flags, DDCOLORKEY *color_key) 04542 { 04543 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface(iface); 04544 TRACE("iface %p, flags %#x, color_key %p.\n", iface, flags, color_key); 04545 04546 return ddraw_surface7_SetColorKey(&This->IDirectDrawSurface7_iface, flags, color_key); 04547 } 04548 04549 /***************************************************************************** 04550 * IDirectDrawSurface7::SetPalette 04551 * 04552 * Assigns a DirectDrawPalette object to the surface 04553 * 04554 * Params: 04555 * Pal: Interface to the palette to set 04556 * 04557 * Returns: 04558 * DD_OK on success 04559 * 04560 *****************************************************************************/ 04561 static HRESULT WINAPI ddraw_surface7_SetPalette(IDirectDrawSurface7 *iface, IDirectDrawPalette *Pal) 04562 { 04563 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface7(iface); 04564 IDirectDrawPalette *oldPal; 04565 IDirectDrawSurfaceImpl *surf; 04566 IDirectDrawPaletteImpl *PalImpl = unsafe_impl_from_IDirectDrawPalette(Pal); 04567 HRESULT hr; 04568 04569 TRACE("iface %p, palette %p.\n", iface, Pal); 04570 04571 if (!(This->surface_desc.u4.ddpfPixelFormat.dwFlags & (DDPF_PALETTEINDEXED1 | DDPF_PALETTEINDEXED2 | 04572 DDPF_PALETTEINDEXED4 | DDPF_PALETTEINDEXED8 | DDPF_PALETTEINDEXEDTO8))) { 04573 return DDERR_INVALIDPIXELFORMAT; 04574 } 04575 04576 if (This->surface_desc.ddsCaps.dwCaps2 & DDSCAPS2_MIPMAPSUBLEVEL) 04577 { 04578 return DDERR_NOTONMIPMAPSUBLEVEL; 04579 } 04580 04581 /* Find the old palette */ 04582 wined3d_mutex_lock(); 04583 hr = IDirectDrawSurface_GetPalette(iface, &oldPal); 04584 if(hr != DD_OK && hr != DDERR_NOPALETTEATTACHED) 04585 { 04586 wined3d_mutex_unlock(); 04587 return hr; 04588 } 04589 if(oldPal) IDirectDrawPalette_Release(oldPal); /* For the GetPalette */ 04590 04591 /* Set the new Palette */ 04592 wined3d_surface_set_palette(This->wined3d_surface, PalImpl ? PalImpl->wineD3DPalette : NULL); 04593 /* AddRef the Palette */ 04594 if(Pal) IDirectDrawPalette_AddRef(Pal); 04595 04596 /* Release the old palette */ 04597 if(oldPal) IDirectDrawPalette_Release(oldPal); 04598 04599 /* Update the wined3d frontbuffer if this is the frontbuffer. */ 04600 if ((This->surface_desc.ddsCaps.dwCaps & DDSCAPS_FRONTBUFFER) && This->ddraw->wined3d_frontbuffer) 04601 { 04602 hr = wined3d_surface_set_palette(This->ddraw->wined3d_frontbuffer, PalImpl ? PalImpl->wineD3DPalette : NULL); 04603 if (FAILED(hr)) 04604 ERR("Failed to set frontbuffer palette, hr %#x.\n", hr); 04605 } 04606 04607 /* If this is a front buffer, also update the back buffers 04608 * TODO: How do things work for palettized cube textures? 04609 */ 04610 if(This->surface_desc.ddsCaps.dwCaps & DDSCAPS_FRONTBUFFER) 04611 { 04612 /* For primary surfaces the tree is just a list, so the simpler scheme fits too */ 04613 DDSCAPS2 caps2 = { DDSCAPS_PRIMARYSURFACE, 0, 0, {0} }; 04614 04615 surf = This; 04616 while(1) 04617 { 04618 IDirectDrawSurface7 *attach; 04619 HRESULT hr; 04620 hr = ddraw_surface7_GetAttachedSurface(&surf->IDirectDrawSurface7_iface, &caps2, &attach); 04621 if(hr != DD_OK) 04622 { 04623 break; 04624 } 04625 04626 TRACE("Setting palette on %p\n", attach); 04627 ddraw_surface7_SetPalette(attach, Pal); 04628 surf = impl_from_IDirectDrawSurface7(attach); 04629 ddraw_surface7_Release(attach); 04630 } 04631 } 04632 04633 wined3d_mutex_unlock(); 04634 04635 return DD_OK; 04636 } 04637 04638 static HRESULT WINAPI ddraw_surface4_SetPalette(IDirectDrawSurface4 *iface, IDirectDrawPalette *palette) 04639 { 04640 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface4(iface); 04641 TRACE("iface %p, palette %p.\n", iface, palette); 04642 04643 return ddraw_surface7_SetPalette(&This->IDirectDrawSurface7_iface, palette); 04644 } 04645 04646 static HRESULT WINAPI ddraw_surface3_SetPalette(IDirectDrawSurface3 *iface, IDirectDrawPalette *palette) 04647 { 04648 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface3(iface); 04649 TRACE("iface %p, palette %p.\n", iface, palette); 04650 04651 return ddraw_surface7_SetPalette(&This->IDirectDrawSurface7_iface, palette); 04652 } 04653 04654 static HRESULT WINAPI ddraw_surface2_SetPalette(IDirectDrawSurface2 *iface, IDirectDrawPalette *palette) 04655 { 04656 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface2(iface); 04657 TRACE("iface %p, palette %p.\n", iface, palette); 04658 04659 return ddraw_surface7_SetPalette(&This->IDirectDrawSurface7_iface, palette); 04660 } 04661 04662 static HRESULT WINAPI ddraw_surface1_SetPalette(IDirectDrawSurface *iface, IDirectDrawPalette *palette) 04663 { 04664 IDirectDrawSurfaceImpl *This = impl_from_IDirectDrawSurface(iface); 04665 TRACE("iface %p, palette %p.\n", iface, palette); 04666 04667 return ddraw_surface7_SetPalette(&This->IDirectDrawSurface7_iface, palette); 04668 } 04669 04670 /********************************************************** 04671 * IDirectDrawGammaControl::GetGammaRamp 04672 * 04673 * Returns the current gamma ramp for a surface 04674 * 04675 * Params: 04676 * flags: Ignored 04677 * gamma_ramp: Address to write the ramp to 04678 * 04679 * Returns: 04680 * DD_OK on success 04681 * DDERR_INVALIDPARAMS if gamma_ramp is NULL 04682 * 04683 **********************************************************/ 04684 static HRESULT WINAPI ddraw_gamma_control_GetGammaRamp(IDirectDrawGammaControl *iface, 04685 DWORD flags, DDGAMMARAMP *gamma_ramp) 04686 { 04687 IDirectDrawSurfaceImpl *surface = impl_from_IDirectDrawGammaControl(iface); 04688 04689 TRACE("iface %p, flags %#x, gamma_ramp %p.\n", iface, flags, gamma_ramp); 04690 04691 if (!gamma_ramp) 04692 { 04693 WARN("Invalid gamma_ramp passed.\n"); 04694 return DDERR_INVALIDPARAMS; 04695 } 04696 04697 wined3d_mutex_lock(); 04698 if (surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) 04699 { 04700 /* Note: DDGAMMARAMP is compatible with struct wined3d_gamma_ramp. */ 04701 wined3d_device_get_gamma_ramp(surface->ddraw->wined3d_device, 0, (struct wined3d_gamma_ramp *)gamma_ramp); 04702 } 04703 else 04704 { 04705 ERR("Not implemented for non-primary surfaces.\n"); 04706 } 04707 wined3d_mutex_unlock(); 04708 04709 return DD_OK; 04710 } 04711 04712 /********************************************************** 04713 * IDirectDrawGammaControl::SetGammaRamp 04714 * 04715 * Sets the red, green and blue gamma ramps for 04716 * 04717 * Params: 04718 * flags: Can be DDSGR_CALIBRATE to request calibration 04719 * gamma_ramp: Structure containing the new gamma ramp 04720 * 04721 * Returns: 04722 * DD_OK on success 04723 * DDERR_INVALIDPARAMS if gamma_ramp is NULL 04724 * 04725 **********************************************************/ 04726 static HRESULT WINAPI ddraw_gamma_control_SetGammaRamp(IDirectDrawGammaControl *iface, 04727 DWORD flags, DDGAMMARAMP *gamma_ramp) 04728 { 04729 IDirectDrawSurfaceImpl *surface = impl_from_IDirectDrawGammaControl(iface); 04730 04731 TRACE("iface %p, flags %#x, gamma_ramp %p.\n", iface, flags, gamma_ramp); 04732 04733 if (!gamma_ramp) 04734 { 04735 WARN("Invalid gamma_ramp passed.\n"); 04736 return DDERR_INVALIDPARAMS; 04737 } 04738 04739 wined3d_mutex_lock(); 04740 if (surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) 04741 { 04742 /* Note: DDGAMMARAMP is compatible with struct wined3d_gamma_ramp. */ 04743 wined3d_device_set_gamma_ramp(surface->ddraw->wined3d_device, 04744 0, flags, (struct wined3d_gamma_ramp *)gamma_ramp); 04745 } 04746 else 04747 { 04748 ERR("Not implemented for non-primary surfaces.\n"); 04749 } 04750 wined3d_mutex_unlock(); 04751 04752 return DD_OK; 04753 } 04754 04755 /***************************************************************************** 04756 * IDirect3DTexture2::PaletteChanged 04757 * 04758 * Informs the texture about a palette change 04759 * 04760 * Params: 04761 * start: Start index of the change 04762 * count: The number of changed entries 04763 * 04764 * Returns 04765 * D3D_OK, because it's a stub 04766 * 04767 *****************************************************************************/ 04768 static HRESULT WINAPI d3d_texture2_PaletteChanged(IDirect3DTexture2 *iface, DWORD start, DWORD count) 04769 { 04770 FIXME("iface %p, start %u, count %u stub!\n", iface, start, count); 04771 04772 return D3D_OK; 04773 } 04774 04775 static HRESULT WINAPI d3d_texture1_PaletteChanged(IDirect3DTexture *iface, DWORD start, DWORD count) 04776 { 04777 IDirectDrawSurfaceImpl *surface = impl_from_IDirect3DTexture(iface); 04778 04779 TRACE("iface %p, start %u, count %u.\n", iface, start, count); 04780 04781 return d3d_texture2_PaletteChanged(&surface->IDirect3DTexture2_iface, start, count); 04782 } 04783 04784 /***************************************************************************** 04785 * IDirect3DTexture::Unload 04786 * 04787 * DX5 SDK: "The IDirect3DTexture2::Unload method is not implemented 04788 * 04789 * 04790 * Returns: 04791 * DDERR_UNSUPPORTED 04792 * 04793 *****************************************************************************/ 04794 static HRESULT WINAPI d3d_texture1_Unload(IDirect3DTexture *iface) 04795 { 04796 WARN("iface %p. Not implemented.\n", iface); 04797 04798 return DDERR_UNSUPPORTED; 04799 } 04800 04801 /***************************************************************************** 04802 * IDirect3DTexture2::GetHandle 04803 * 04804 * Returns handle for the texture. At the moment, the interface 04805 * to the IWineD3DTexture is used. 04806 * 04807 * Params: 04808 * device: Device this handle is assigned to 04809 * handle: Address to store the handle at. 04810 * 04811 * Returns: 04812 * D3D_OK 04813 * 04814 *****************************************************************************/ 04815 static HRESULT WINAPI d3d_texture2_GetHandle(IDirect3DTexture2 *iface, 04816 IDirect3DDevice2 *device, D3DTEXTUREHANDLE *handle) 04817 { 04818 IDirectDrawSurfaceImpl *surface = impl_from_IDirect3DTexture2(iface); 04819 IDirect3DDeviceImpl *device_impl = unsafe_impl_from_IDirect3DDevice2(device); 04820 04821 TRACE("iface %p, device %p, handle %p.\n", iface, device, handle); 04822 04823 wined3d_mutex_lock(); 04824 04825 if (!surface->Handle) 04826 { 04827 DWORD h = ddraw_allocate_handle(&device_impl->handle_table, surface, DDRAW_HANDLE_SURFACE); 04828 if (h == DDRAW_INVALID_HANDLE) 04829 { 04830 ERR("Failed to allocate a texture handle.\n"); 04831 wined3d_mutex_unlock(); 04832 return DDERR_OUTOFMEMORY; 04833 } 04834 04835 surface->Handle = h + 1; 04836 } 04837 04838 TRACE("Returning handle %08x.\n", surface->Handle); 04839 *handle = surface->Handle; 04840 04841 wined3d_mutex_unlock(); 04842 04843 return D3D_OK; 04844 } 04845 04846 static HRESULT WINAPI d3d_texture1_GetHandle(IDirect3DTexture *iface, 04847 IDirect3DDevice *device, D3DTEXTUREHANDLE *handle) 04848 { 04849 IDirectDrawSurfaceImpl *This = impl_from_IDirect3DTexture(iface); 04850 IDirect3DDeviceImpl *device_impl = unsafe_impl_from_IDirect3DDevice(device); 04851 04852 TRACE("iface %p, device %p, handle %p.\n", iface, device, handle); 04853 04854 return d3d_texture2_GetHandle(&This->IDirect3DTexture2_iface, 04855 device_impl ? &device_impl->IDirect3DDevice2_iface : NULL, handle); 04856 } 04857 04858 /***************************************************************************** 04859 * get_sub_mimaplevel 04860 * 04861 * Helper function that returns the next mipmap level 04862 * 04863 * tex_ptr: Surface of which to return the next level 04864 * 04865 *****************************************************************************/ 04866 static IDirectDrawSurfaceImpl *get_sub_mimaplevel(IDirectDrawSurfaceImpl *surface) 04867 { 04868 /* Now go down the mipmap chain to the next surface */ 04869 static DDSCAPS2 mipmap_caps = { DDSCAPS_MIPMAP | DDSCAPS_TEXTURE, 0, 0, {0} }; 04870 IDirectDrawSurface7 *next_level; 04871 HRESULT hr; 04872 04873 hr = ddraw_surface7_GetAttachedSurface(&surface->IDirectDrawSurface7_iface, &mipmap_caps, &next_level); 04874 if (FAILED(hr)) return NULL; 04875 04876 ddraw_surface7_Release(next_level); 04877 04878 return impl_from_IDirectDrawSurface7(next_level); 04879 } 04880 04881 /***************************************************************************** 04882 * IDirect3DTexture2::Load 04883 * 04884 * Loads a texture created with the DDSCAPS_ALLOCONLOAD 04885 * 04886 * This function isn't relayed to WineD3D because the whole interface is 04887 * implemented in DDraw only. For speed improvements a implementation which 04888 * takes OpenGL more into account could be placed into WineD3D. 04889 * 04890 * Params: 04891 * src_texture: Address of the texture to load 04892 * 04893 * Returns: 04894 * D3D_OK on success 04895 * D3DERR_TEXTURE_LOAD_FAILED. 04896 * 04897 *****************************************************************************/ 04898 static HRESULT WINAPI d3d_texture2_Load(IDirect3DTexture2 *iface, IDirect3DTexture2 *src_texture) 04899 { 04900 IDirectDrawSurfaceImpl *dst_surface = impl_from_IDirect3DTexture2(iface); 04901 IDirectDrawSurfaceImpl *src_surface = unsafe_impl_from_IDirect3DTexture2(src_texture); 04902 HRESULT hr; 04903 04904 TRACE("iface %p, src_texture %p.\n", iface, src_texture); 04905 04906 if (src_surface == dst_surface) 04907 { 04908 TRACE("copying surface %p to surface %p, why?\n", src_surface, dst_surface); 04909 return D3D_OK; 04910 } 04911 04912 wined3d_mutex_lock(); 04913 04914 if (((src_surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_MIPMAP) 04915 != (dst_surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_MIPMAP)) 04916 || (src_surface->surface_desc.u2.dwMipMapCount != dst_surface->surface_desc.u2.dwMipMapCount)) 04917 { 04918 ERR("Trying to load surfaces with different mip-map counts.\n"); 04919 } 04920 04921 for (;;) 04922 { 04923 struct wined3d_palette *wined3d_dst_pal, *wined3d_src_pal; 04924 IDirectDrawPalette *dst_pal = NULL, *src_pal = NULL; 04925 DDSURFACEDESC *src_desc, *dst_desc; 04926 04927 TRACE("Copying surface %p to surface %p (mipmap level %d).\n", 04928 src_surface, dst_surface, src_surface->mipmap_level); 04929 04930 /* Suppress the ALLOCONLOAD flag */ 04931 dst_surface->surface_desc.ddsCaps.dwCaps &= ~DDSCAPS_ALLOCONLOAD; 04932 04933 /* Get the palettes */ 04934 wined3d_dst_pal = wined3d_surface_get_palette(dst_surface->wined3d_surface); 04935 if (wined3d_dst_pal) 04936 dst_pal = wined3d_palette_get_parent(wined3d_dst_pal); 04937 04938 wined3d_src_pal = wined3d_surface_get_palette(src_surface->wined3d_surface); 04939 if (wined3d_src_pal) 04940 src_pal = wined3d_palette_get_parent(wined3d_src_pal); 04941 04942 if (src_pal) 04943 { 04944 PALETTEENTRY palent[256]; 04945 04946 if (!dst_pal) 04947 { 04948 wined3d_mutex_unlock(); 04949 return DDERR_NOPALETTEATTACHED; 04950 } 04951 IDirectDrawPalette_GetEntries(src_pal, 0, 0, 256, palent); 04952 IDirectDrawPalette_SetEntries(dst_pal, 0, 0, 256, palent); 04953 } 04954 04955 /* Copy one surface on the other */ 04956 dst_desc = (DDSURFACEDESC *)&(dst_surface->surface_desc); 04957 src_desc = (DDSURFACEDESC *)&(src_surface->surface_desc); 04958 04959 if ((src_desc->dwWidth != dst_desc->dwWidth) || (src_desc->dwHeight != dst_desc->dwHeight)) 04960 { 04961 /* Should also check for same pixel format, u1.lPitch, ... */ 04962 ERR("Error in surface sizes.\n"); 04963 wined3d_mutex_unlock(); 04964 return D3DERR_TEXTURE_LOAD_FAILED; 04965 } 04966 else 04967 { 04968 struct wined3d_mapped_rect src_rect, dst_rect; 04969 04970 /* Copy also the ColorKeying stuff */ 04971 if (src_desc->dwFlags & DDSD_CKSRCBLT) 04972 { 04973 dst_desc->dwFlags |= DDSD_CKSRCBLT; 04974 dst_desc->ddckCKSrcBlt.dwColorSpaceLowValue = src_desc->ddckCKSrcBlt.dwColorSpaceLowValue; 04975 dst_desc->ddckCKSrcBlt.dwColorSpaceHighValue = src_desc->ddckCKSrcBlt.dwColorSpaceHighValue; 04976 } 04977 04978 /* Copy the main memory texture into the surface that corresponds 04979 * to the OpenGL texture object. */ 04980 04981 hr = wined3d_surface_map(src_surface->wined3d_surface, &src_rect, NULL, 0); 04982 if (FAILED(hr)) 04983 { 04984 ERR("Failed to lock source surface, hr %#x.\n", hr); 04985 wined3d_mutex_unlock(); 04986 return D3DERR_TEXTURE_LOAD_FAILED; 04987 } 04988 04989 hr = wined3d_surface_map(dst_surface->wined3d_surface, &dst_rect, NULL, 0); 04990 if (FAILED(hr)) 04991 { 04992 ERR("Failed to lock destination surface, hr %#x.\n", hr); 04993 wined3d_surface_unmap(src_surface->wined3d_surface); 04994 wined3d_mutex_unlock(); 04995 return D3DERR_TEXTURE_LOAD_FAILED; 04996 } 04997 04998 if (dst_surface->surface_desc.u4.ddpfPixelFormat.dwFlags & DDPF_FOURCC) 04999 memcpy(dst_rect.data, src_rect.data, src_surface->surface_desc.u1.dwLinearSize); 05000 else 05001 memcpy(dst_rect.data, src_rect.data, src_rect.row_pitch * src_desc->dwHeight); 05002 05003 wined3d_surface_unmap(src_surface->wined3d_surface); 05004 wined3d_surface_unmap(dst_surface->wined3d_surface); 05005 } 05006 05007 if (src_surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_MIPMAP) 05008 src_surface = get_sub_mimaplevel(src_surface); 05009 else 05010 src_surface = NULL; 05011 05012 if (dst_surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_MIPMAP) 05013 dst_surface = get_sub_mimaplevel(dst_surface); 05014 else 05015 dst_surface = NULL; 05016 05017 if (!src_surface || !dst_surface) 05018 { 05019 if (src_surface != dst_surface) 05020 ERR("Loading surface with different mipmap structure.\n"); 05021 break; 05022 } 05023 } 05024 05025 wined3d_mutex_unlock(); 05026 05027 return hr; 05028 } 05029 05030 static HRESULT WINAPI d3d_texture1_Load(IDirect3DTexture *iface, IDirect3DTexture *src_texture) 05031 { 05032 IDirectDrawSurfaceImpl* This = impl_from_IDirect3DTexture(iface); 05033 IDirectDrawSurfaceImpl* src_surface = unsafe_impl_from_IDirect3DTexture(src_texture); 05034 TRACE("iface %p, src_texture %p.\n", iface, src_texture); 05035 05036 return d3d_texture2_Load(&This->IDirect3DTexture2_iface, 05037 src_surface ? &src_surface->IDirect3DTexture2_iface : NULL); 05038 } 05039 05040 /***************************************************************************** 05041 * The VTable 05042 *****************************************************************************/ 05043 05044 static const struct IDirectDrawSurface7Vtbl ddraw_surface7_vtbl = 05045 { 05046 /* IUnknown */ 05047 ddraw_surface7_QueryInterface, 05048 ddraw_surface7_AddRef, 05049 ddraw_surface7_Release, 05050 /* IDirectDrawSurface */ 05051 ddraw_surface7_AddAttachedSurface, 05052 ddraw_surface7_AddOverlayDirtyRect, 05053 ddraw_surface7_Blt, 05054 ddraw_surface7_BltBatch, 05055 ddraw_surface7_BltFast, 05056 ddraw_surface7_DeleteAttachedSurface, 05057 ddraw_surface7_EnumAttachedSurfaces, 05058 ddraw_surface7_EnumOverlayZOrders, 05059 ddraw_surface7_Flip, 05060 ddraw_surface7_GetAttachedSurface, 05061 ddraw_surface7_GetBltStatus, 05062 ddraw_surface7_GetCaps, 05063 ddraw_surface7_GetClipper, 05064 ddraw_surface7_GetColorKey, 05065 ddraw_surface7_GetDC, 05066 ddraw_surface7_GetFlipStatus, 05067 ddraw_surface7_GetOverlayPosition, 05068 ddraw_surface7_GetPalette, 05069 ddraw_surface7_GetPixelFormat, 05070 ddraw_surface7_GetSurfaceDesc, 05071 ddraw_surface7_Initialize, 05072 ddraw_surface7_IsLost, 05073 ddraw_surface7_Lock, 05074 ddraw_surface7_ReleaseDC, 05075 ddraw_surface7_Restore, 05076 ddraw_surface7_SetClipper, 05077 ddraw_surface7_SetColorKey, 05078 ddraw_surface7_SetOverlayPosition, 05079 ddraw_surface7_SetPalette, 05080 ddraw_surface7_Unlock, 05081 ddraw_surface7_UpdateOverlay, 05082 ddraw_surface7_UpdateOverlayDisplay, 05083 ddraw_surface7_UpdateOverlayZOrder, 05084 /* IDirectDrawSurface2 */ 05085 ddraw_surface7_GetDDInterface, 05086 ddraw_surface7_PageLock, 05087 ddraw_surface7_PageUnlock, 05088 /* IDirectDrawSurface3 */ 05089 ddraw_surface7_SetSurfaceDesc, 05090 /* IDirectDrawSurface4 */ 05091 ddraw_surface7_SetPrivateData, 05092 ddraw_surface7_GetPrivateData, 05093 ddraw_surface7_FreePrivateData, 05094 ddraw_surface7_GetUniquenessValue, 05095 ddraw_surface7_ChangeUniquenessValue, 05096 /* IDirectDrawSurface7 */ 05097 ddraw_surface7_SetPriority, 05098 ddraw_surface7_GetPriority, 05099 ddraw_surface7_SetLOD, 05100 ddraw_surface7_GetLOD, 05101 }; 05102 05103 static const struct IDirectDrawSurface4Vtbl ddraw_surface4_vtbl = 05104 { 05105 /* IUnknown */ 05106 ddraw_surface4_QueryInterface, 05107 ddraw_surface4_AddRef, 05108 ddraw_surface4_Release, 05109 /* IDirectDrawSurface */ 05110 ddraw_surface4_AddAttachedSurface, 05111 ddraw_surface4_AddOverlayDirtyRect, 05112 ddraw_surface4_Blt, 05113 ddraw_surface4_BltBatch, 05114 ddraw_surface4_BltFast, 05115 ddraw_surface4_DeleteAttachedSurface, 05116 ddraw_surface4_EnumAttachedSurfaces, 05117 ddraw_surface4_EnumOverlayZOrders, 05118 ddraw_surface4_Flip, 05119 ddraw_surface4_GetAttachedSurface, 05120 ddraw_surface4_GetBltStatus, 05121 ddraw_surface4_GetCaps, 05122 ddraw_surface4_GetClipper, 05123 ddraw_surface4_GetColorKey, 05124 ddraw_surface4_GetDC, 05125 ddraw_surface4_GetFlipStatus, 05126 ddraw_surface4_GetOverlayPosition, 05127 ddraw_surface4_GetPalette, 05128 ddraw_surface4_GetPixelFormat, 05129 ddraw_surface4_GetSurfaceDesc, 05130 ddraw_surface4_Initialize, 05131 ddraw_surface4_IsLost, 05132 ddraw_surface4_Lock, 05133 ddraw_surface4_ReleaseDC, 05134 ddraw_surface4_Restore, 05135 ddraw_surface4_SetClipper, 05136 ddraw_surface4_SetColorKey, 05137 ddraw_surface4_SetOverlayPosition, 05138 ddraw_surface4_SetPalette, 05139 ddraw_surface4_Unlock, 05140 ddraw_surface4_UpdateOverlay, 05141 ddraw_surface4_UpdateOverlayDisplay, 05142 ddraw_surface4_UpdateOverlayZOrder, 05143 /* IDirectDrawSurface2 */ 05144 ddraw_surface4_GetDDInterface, 05145 ddraw_surface4_PageLock, 05146 ddraw_surface4_PageUnlock, 05147 /* IDirectDrawSurface3 */ 05148 ddraw_surface4_SetSurfaceDesc, 05149 /* IDirectDrawSurface4 */ 05150 ddraw_surface4_SetPrivateData, 05151 ddraw_surface4_GetPrivateData, 05152 ddraw_surface4_FreePrivateData, 05153 ddraw_surface4_GetUniquenessValue, 05154 ddraw_surface4_ChangeUniquenessValue, 05155 }; 05156 05157 static const struct IDirectDrawSurface3Vtbl ddraw_surface3_vtbl = 05158 { 05159 /* IUnknown */ 05160 ddraw_surface3_QueryInterface, 05161 ddraw_surface3_AddRef, 05162 ddraw_surface3_Release, 05163 /* IDirectDrawSurface */ 05164 ddraw_surface3_AddAttachedSurface, 05165 ddraw_surface3_AddOverlayDirtyRect, 05166 ddraw_surface3_Blt, 05167 ddraw_surface3_BltBatch, 05168 ddraw_surface3_BltFast, 05169 ddraw_surface3_DeleteAttachedSurface, 05170 ddraw_surface3_EnumAttachedSurfaces, 05171 ddraw_surface3_EnumOverlayZOrders, 05172 ddraw_surface3_Flip, 05173 ddraw_surface3_GetAttachedSurface, 05174 ddraw_surface3_GetBltStatus, 05175 ddraw_surface3_GetCaps, 05176 ddraw_surface3_GetClipper, 05177 ddraw_surface3_GetColorKey, 05178 ddraw_surface3_GetDC, 05179 ddraw_surface3_GetFlipStatus, 05180 ddraw_surface3_GetOverlayPosition, 05181 ddraw_surface3_GetPalette, 05182 ddraw_surface3_GetPixelFormat, 05183 ddraw_surface3_GetSurfaceDesc, 05184 ddraw_surface3_Initialize, 05185 ddraw_surface3_IsLost, 05186 ddraw_surface3_Lock, 05187 ddraw_surface3_ReleaseDC, 05188 ddraw_surface3_Restore, 05189 ddraw_surface3_SetClipper, 05190 ddraw_surface3_SetColorKey, 05191 ddraw_surface3_SetOverlayPosition, 05192 ddraw_surface3_SetPalette, 05193 ddraw_surface3_Unlock, 05194 ddraw_surface3_UpdateOverlay, 05195 ddraw_surface3_UpdateOverlayDisplay, 05196 ddraw_surface3_UpdateOverlayZOrder, 05197 /* IDirectDrawSurface2 */ 05198 ddraw_surface3_GetDDInterface, 05199 ddraw_surface3_PageLock, 05200 ddraw_surface3_PageUnlock, 05201 /* IDirectDrawSurface3 */ 05202 ddraw_surface3_SetSurfaceDesc, 05203 }; 05204 05205 static const struct IDirectDrawSurface2Vtbl ddraw_surface2_vtbl = 05206 { 05207 /* IUnknown */ 05208 ddraw_surface2_QueryInterface, 05209 ddraw_surface2_AddRef, 05210 ddraw_surface2_Release, 05211 /* IDirectDrawSurface */ 05212 ddraw_surface2_AddAttachedSurface, 05213 ddraw_surface2_AddOverlayDirtyRect, 05214 ddraw_surface2_Blt, 05215 ddraw_surface2_BltBatch, 05216 ddraw_surface2_BltFast, 05217 ddraw_surface2_DeleteAttachedSurface, 05218 ddraw_surface2_EnumAttachedSurfaces, 05219 ddraw_surface2_EnumOverlayZOrders, 05220 ddraw_surface2_Flip, 05221 ddraw_surface2_GetAttachedSurface, 05222 ddraw_surface2_GetBltStatus, 05223 ddraw_surface2_GetCaps, 05224 ddraw_surface2_GetClipper, 05225 ddraw_surface2_GetColorKey, 05226 ddraw_surface2_GetDC, 05227 ddraw_surface2_GetFlipStatus, 05228 ddraw_surface2_GetOverlayPosition, 05229 ddraw_surface2_GetPalette, 05230 ddraw_surface2_GetPixelFormat, 05231 ddraw_surface2_GetSurfaceDesc, 05232 ddraw_surface2_Initialize, 05233 ddraw_surface2_IsLost, 05234 ddraw_surface2_Lock, 05235 ddraw_surface2_ReleaseDC, 05236 ddraw_surface2_Restore, 05237 ddraw_surface2_SetClipper, 05238 ddraw_surface2_SetColorKey, 05239 ddraw_surface2_SetOverlayPosition, 05240 ddraw_surface2_SetPalette, 05241 ddraw_surface2_Unlock, 05242 ddraw_surface2_UpdateOverlay, 05243 ddraw_surface2_UpdateOverlayDisplay, 05244 ddraw_surface2_UpdateOverlayZOrder, 05245 /* IDirectDrawSurface2 */ 05246 ddraw_surface2_GetDDInterface, 05247 ddraw_surface2_PageLock, 05248 ddraw_surface2_PageUnlock, 05249 }; 05250 05251 static const struct IDirectDrawSurfaceVtbl ddraw_surface1_vtbl = 05252 { 05253 /* IUnknown */ 05254 ddraw_surface1_QueryInterface, 05255 ddraw_surface1_AddRef, 05256 ddraw_surface1_Release, 05257 /* IDirectDrawSurface */ 05258 ddraw_surface1_AddAttachedSurface, 05259 ddraw_surface1_AddOverlayDirtyRect, 05260 ddraw_surface1_Blt, 05261 ddraw_surface1_BltBatch, 05262 ddraw_surface1_BltFast, 05263 ddraw_surface1_DeleteAttachedSurface, 05264 ddraw_surface1_EnumAttachedSurfaces, 05265 ddraw_surface1_EnumOverlayZOrders, 05266 ddraw_surface1_Flip, 05267 ddraw_surface1_GetAttachedSurface, 05268 ddraw_surface1_GetBltStatus, 05269 ddraw_surface1_GetCaps, 05270 ddraw_surface1_GetClipper, 05271 ddraw_surface1_GetColorKey, 05272 ddraw_surface1_GetDC, 05273 ddraw_surface1_GetFlipStatus, 05274 ddraw_surface1_GetOverlayPosition, 05275 ddraw_surface1_GetPalette, 05276 ddraw_surface1_GetPixelFormat, 05277 ddraw_surface1_GetSurfaceDesc, 05278 ddraw_surface1_Initialize, 05279 ddraw_surface1_IsLost, 05280 ddraw_surface1_Lock, 05281 ddraw_surface1_ReleaseDC, 05282 ddraw_surface1_Restore, 05283 ddraw_surface1_SetClipper, 05284 ddraw_surface1_SetColorKey, 05285 ddraw_surface1_SetOverlayPosition, 05286 ddraw_surface1_SetPalette, 05287 ddraw_surface1_Unlock, 05288 ddraw_surface1_UpdateOverlay, 05289 ddraw_surface1_UpdateOverlayDisplay, 05290 ddraw_surface1_UpdateOverlayZOrder, 05291 }; 05292 05293 static const struct IDirectDrawGammaControlVtbl ddraw_gamma_control_vtbl = 05294 { 05295 ddraw_gamma_control_QueryInterface, 05296 ddraw_gamma_control_AddRef, 05297 ddraw_gamma_control_Release, 05298 ddraw_gamma_control_GetGammaRamp, 05299 ddraw_gamma_control_SetGammaRamp, 05300 }; 05301 05302 static const struct IDirect3DTexture2Vtbl d3d_texture2_vtbl = 05303 { 05304 d3d_texture2_QueryInterface, 05305 d3d_texture2_AddRef, 05306 d3d_texture2_Release, 05307 d3d_texture2_GetHandle, 05308 d3d_texture2_PaletteChanged, 05309 d3d_texture2_Load, 05310 }; 05311 05312 static const struct IDirect3DTextureVtbl d3d_texture1_vtbl = 05313 { 05314 d3d_texture1_QueryInterface, 05315 d3d_texture1_AddRef, 05316 d3d_texture1_Release, 05317 d3d_texture1_Initialize, 05318 d3d_texture1_GetHandle, 05319 d3d_texture1_PaletteChanged, 05320 d3d_texture1_Load, 05321 d3d_texture1_Unload, 05322 }; 05323 05324 IDirectDrawSurfaceImpl *unsafe_impl_from_IDirectDrawSurface7(IDirectDrawSurface7 *iface) 05325 { 05326 if (!iface) return NULL; 05327 assert(iface->lpVtbl == &ddraw_surface7_vtbl); 05328 return CONTAINING_RECORD(iface, IDirectDrawSurfaceImpl, IDirectDrawSurface7_iface); 05329 } 05330 05331 IDirectDrawSurfaceImpl *unsafe_impl_from_IDirectDrawSurface4(IDirectDrawSurface4 *iface) 05332 { 05333 if (!iface) return NULL; 05334 assert(iface->lpVtbl == &ddraw_surface4_vtbl); 05335 return CONTAINING_RECORD(iface, IDirectDrawSurfaceImpl, IDirectDrawSurface4_iface); 05336 } 05337 05338 static IDirectDrawSurfaceImpl *unsafe_impl_from_IDirectDrawSurface3(IDirectDrawSurface3 *iface) 05339 { 05340 if (!iface) return NULL; 05341 assert(iface->lpVtbl == &ddraw_surface3_vtbl); 05342 return CONTAINING_RECORD(iface, IDirectDrawSurfaceImpl, IDirectDrawSurface3_iface); 05343 } 05344 05345 static IDirectDrawSurfaceImpl *unsafe_impl_from_IDirectDrawSurface2(IDirectDrawSurface2 *iface) 05346 { 05347 if (!iface) return NULL; 05348 assert(iface->lpVtbl == &ddraw_surface2_vtbl); 05349 return CONTAINING_RECORD(iface, IDirectDrawSurfaceImpl, IDirectDrawSurface2_iface); 05350 } 05351 05352 IDirectDrawSurfaceImpl *unsafe_impl_from_IDirectDrawSurface(IDirectDrawSurface *iface) 05353 { 05354 if (!iface) return NULL; 05355 assert(iface->lpVtbl == &ddraw_surface1_vtbl); 05356 return CONTAINING_RECORD(iface, IDirectDrawSurfaceImpl, IDirectDrawSurface_iface); 05357 } 05358 05359 IDirectDrawSurfaceImpl *unsafe_impl_from_IDirect3DTexture2(IDirect3DTexture2 *iface) 05360 { 05361 if (!iface) return NULL; 05362 assert(iface->lpVtbl == &d3d_texture2_vtbl); 05363 return CONTAINING_RECORD(iface, IDirectDrawSurfaceImpl, IDirect3DTexture2_iface); 05364 } 05365 05366 IDirectDrawSurfaceImpl *unsafe_impl_from_IDirect3DTexture(IDirect3DTexture *iface) 05367 { 05368 if (!iface) return NULL; 05369 assert(iface->lpVtbl == &d3d_texture1_vtbl); 05370 return CONTAINING_RECORD(iface, IDirectDrawSurfaceImpl, IDirect3DTexture_iface); 05371 } 05372 05373 static void STDMETHODCALLTYPE ddraw_surface_wined3d_object_destroyed(void *parent) 05374 { 05375 IDirectDrawSurfaceImpl *surface = parent; 05376 05377 TRACE("surface %p.\n", surface); 05378 05379 /* Check for attached surfaces and detach them. */ 05380 if (surface->first_attached != surface) 05381 { 05382 /* Well, this shouldn't happen: The surface being attached is 05383 * referenced in AddAttachedSurface(), so it shouldn't be released 05384 * until DeleteAttachedSurface() is called, because the refcount is 05385 * held. It looks like the application released it often enough to 05386 * force this. */ 05387 WARN("Surface is still attached to surface %p.\n", surface->first_attached); 05388 05389 /* The refcount will drop to -1 here */ 05390 if (FAILED(ddraw_surface_delete_attached_surface(surface->first_attached, surface, surface->attached_iface))) 05391 ERR("DeleteAttachedSurface failed.\n"); 05392 } 05393 05394 while (surface->next_attached) 05395 if (FAILED(ddraw_surface_delete_attached_surface(surface, 05396 surface->next_attached, surface->next_attached->attached_iface))) 05397 ERR("DeleteAttachedSurface failed.\n"); 05398 05399 /* Having a texture handle set implies that the device still exists. */ 05400 if (surface->Handle) 05401 ddraw_free_handle(&surface->ddraw->d3ddevice->handle_table, surface->Handle - 1, DDRAW_HANDLE_SURFACE); 05402 05403 /* Reduce the ddraw surface count. */ 05404 list_remove(&surface->surface_list_entry); 05405 05406 if (surface == surface->ddraw->primary) 05407 surface->ddraw->primary = NULL; 05408 05409 HeapFree(GetProcessHeap(), 0, surface); 05410 } 05411 05412 const struct wined3d_parent_ops ddraw_surface_wined3d_parent_ops = 05413 { 05414 ddraw_surface_wined3d_object_destroyed, 05415 }; 05416 05417 static void STDMETHODCALLTYPE ddraw_texture_wined3d_object_destroyed(void *parent) 05418 { 05419 IDirectDrawSurfaceImpl *surface = parent; 05420 05421 TRACE("surface %p.\n", surface); 05422 05423 ddraw_surface_cleanup(surface); 05424 } 05425 05426 static const struct wined3d_parent_ops ddraw_texture_wined3d_parent_ops = 05427 { 05428 ddraw_texture_wined3d_object_destroyed, 05429 }; 05430 05431 HRESULT ddraw_surface_create_texture(IDirectDrawSurfaceImpl *surface) 05432 { 05433 const DDSURFACEDESC2 *desc = &surface->surface_desc; 05434 enum wined3d_format_id format; 05435 enum wined3d_pool pool; 05436 UINT levels; 05437 05438 if (desc->ddsCaps.dwCaps & DDSCAPS_MIPMAP) 05439 levels = desc->u2.dwMipMapCount; 05440 else 05441 levels = 1; 05442 05443 /* DDSCAPS_SYSTEMMEMORY textures are in WINED3D_POOL_SYSTEM_MEM. 05444 * Should I forward the MANAGED cap to the managed pool? */ 05445 if (desc->ddsCaps.dwCaps & DDSCAPS_SYSTEMMEMORY) 05446 pool = WINED3D_POOL_SYSTEM_MEM; 05447 else 05448 pool = WINED3D_POOL_DEFAULT; 05449 05450 format = PixelFormat_DD2WineD3D(&surface->surface_desc.u4.ddpfPixelFormat); 05451 if (desc->ddsCaps.dwCaps2 & DDSCAPS2_CUBEMAP) 05452 return wined3d_texture_create_cube(surface->ddraw->wined3d_device, desc->dwWidth, 05453 levels, 0, format, pool, surface, &ddraw_texture_wined3d_parent_ops, &surface->wined3d_texture); 05454 else 05455 return wined3d_texture_create_2d(surface->ddraw->wined3d_device, desc->dwWidth, desc->dwHeight, 05456 levels, 0, format, pool, surface, &ddraw_texture_wined3d_parent_ops, &surface->wined3d_texture); 05457 } 05458 05459 HRESULT ddraw_surface_init(IDirectDrawSurfaceImpl *surface, IDirectDrawImpl *ddraw, 05460 DDSURFACEDESC2 *desc, UINT mip_level, UINT version) 05461 { 05462 enum wined3d_pool pool = WINED3D_POOL_DEFAULT; 05463 DWORD flags = WINED3D_SURFACE_MAPPABLE; 05464 enum wined3d_format_id format; 05465 DWORD usage = 0; 05466 HRESULT hr; 05467 05468 if (!(desc->ddsCaps.dwCaps & (DDSCAPS_VIDEOMEMORY | DDSCAPS_SYSTEMMEMORY)) 05469 && !((desc->ddsCaps.dwCaps & DDSCAPS_TEXTURE) 05470 && (desc->ddsCaps.dwCaps2 & DDSCAPS2_TEXTUREMANAGE))) 05471 { 05472 /* Tests show surfaces without memory flags get these flags added 05473 * right after creation. */ 05474 desc->ddsCaps.dwCaps |= DDSCAPS_LOCALVIDMEM | DDSCAPS_VIDEOMEMORY; 05475 } 05476 05477 if (desc->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) 05478 { 05479 /* Some applications assume that the primary surface will always be 05480 * mapped at the same address. Some of those also assume that this 05481 * address is valid even when the surface isn't mapped, and that 05482 * updates done this way will be visible on the screen. The game Nox 05483 * is such an application. */ 05484 if (version == 1) 05485 flags |= WINED3D_SURFACE_PIN_SYSMEM; 05486 usage |= WINED3DUSAGE_RENDERTARGET; 05487 desc->ddsCaps.dwCaps |= DDSCAPS_VISIBLE; 05488 } 05489 05490 if ((desc->ddsCaps.dwCaps & DDSCAPS_3DDEVICE) && !(desc->ddsCaps.dwCaps & DDSCAPS_ZBUFFER)) 05491 { 05492 usage |= WINED3DUSAGE_RENDERTARGET; 05493 } 05494 05495 if (desc->ddsCaps.dwCaps & (DDSCAPS_OVERLAY)) 05496 { 05497 usage |= WINED3DUSAGE_OVERLAY; 05498 } 05499 05500 if (desc->ddsCaps.dwCaps & DDSCAPS_ZBUFFER) 05501 usage |= WINED3DUSAGE_DEPTHSTENCIL; 05502 05503 if (desc->ddsCaps.dwCaps & DDSCAPS_OWNDC) 05504 usage |= WINED3DUSAGE_OWNDC; 05505 05506 if (desc->ddsCaps.dwCaps & DDSCAPS_SYSTEMMEMORY) 05507 { 05508 pool = WINED3D_POOL_SYSTEM_MEM; 05509 } 05510 else if (desc->ddsCaps.dwCaps2 & DDSCAPS2_TEXTUREMANAGE) 05511 { 05512 pool = WINED3D_POOL_MANAGED; 05513 /* Managed textures have the system memory flag set. */ 05514 desc->ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY; 05515 } 05516 else if (desc->ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY) 05517 { 05518 /* Videomemory adds localvidmem. This is mutually exclusive with 05519 * systemmemory and texturemanage. */ 05520 desc->ddsCaps.dwCaps |= DDSCAPS_LOCALVIDMEM; 05521 } 05522 05523 format = PixelFormat_DD2WineD3D(&desc->u4.ddpfPixelFormat); 05524 if (format == WINED3DFMT_UNKNOWN) 05525 { 05526 WARN("Unsupported / unknown pixelformat.\n"); 05527 return DDERR_INVALIDPIXELFORMAT; 05528 } 05529 05530 surface->IDirectDrawSurface7_iface.lpVtbl = &ddraw_surface7_vtbl; 05531 surface->IDirectDrawSurface4_iface.lpVtbl = &ddraw_surface4_vtbl; 05532 surface->IDirectDrawSurface3_iface.lpVtbl = &ddraw_surface3_vtbl; 05533 surface->IDirectDrawSurface2_iface.lpVtbl = &ddraw_surface2_vtbl; 05534 surface->IDirectDrawSurface_iface.lpVtbl = &ddraw_surface1_vtbl; 05535 surface->IDirectDrawGammaControl_iface.lpVtbl = &ddraw_gamma_control_vtbl; 05536 surface->IDirect3DTexture2_iface.lpVtbl = &d3d_texture2_vtbl; 05537 surface->IDirect3DTexture_iface.lpVtbl = &d3d_texture1_vtbl; 05538 surface->iface_count = 1; 05539 surface->version = version; 05540 surface->ddraw = ddraw; 05541 05542 if (version == 7) 05543 { 05544 surface->ref7 = 1; 05545 } 05546 else if (version == 4) 05547 { 05548 surface->ref4 = 1; 05549 } 05550 else 05551 { 05552 surface->ref1 = 1; 05553 } 05554 05555 copy_to_surfacedesc2(&surface->surface_desc, desc); 05556 05557 surface->first_attached = surface; 05558 05559 hr = wined3d_surface_create(ddraw->wined3d_device, desc->dwWidth, desc->dwHeight, format, mip_level, 05560 usage, pool, WINED3D_MULTISAMPLE_NONE, 0, DefaultSurfaceType, flags, 05561 surface, &ddraw_surface_wined3d_parent_ops, &surface->wined3d_surface); 05562 if (FAILED(hr)) 05563 { 05564 WARN("Failed to create wined3d surface, hr %#x.\n", hr); 05565 return hr; 05566 } 05567 05568 /* Anno 1602 stores the pitch right after surface creation, so make sure 05569 * it's there. TODO: Test other fourcc formats. */ 05570 if (format == WINED3DFMT_DXT1 || format == WINED3DFMT_DXT2 || format == WINED3DFMT_DXT3 05571 || format == WINED3DFMT_DXT4 || format == WINED3DFMT_DXT5) 05572 { 05573 surface->surface_desc.dwFlags |= DDSD_LINEARSIZE; 05574 if (format == WINED3DFMT_DXT1) 05575 { 05576 surface->surface_desc.u1.dwLinearSize = max(4, desc->dwWidth) * max(4, desc->dwHeight) / 2; 05577 } 05578 else 05579 { 05580 surface->surface_desc.u1.dwLinearSize = max(4, desc->dwWidth) * max(4, desc->dwHeight); 05581 } 05582 } 05583 else 05584 { 05585 surface->surface_desc.dwFlags |= DDSD_PITCH; 05586 surface->surface_desc.u1.lPitch = wined3d_surface_get_pitch(surface->wined3d_surface); 05587 } 05588 05589 if (desc->dwFlags & DDSD_CKDESTOVERLAY) 05590 { 05591 wined3d_surface_set_color_key(surface->wined3d_surface, DDCKEY_DESTOVERLAY, 05592 (struct wined3d_color_key *)&desc->u3.ddckCKDestOverlay); 05593 } 05594 if (desc->dwFlags & DDSD_CKDESTBLT) 05595 { 05596 wined3d_surface_set_color_key(surface->wined3d_surface, DDCKEY_DESTBLT, 05597 (struct wined3d_color_key *)&desc->ddckCKDestBlt); 05598 } 05599 if (desc->dwFlags & DDSD_CKSRCOVERLAY) 05600 { 05601 wined3d_surface_set_color_key(surface->wined3d_surface, DDCKEY_SRCOVERLAY, 05602 (struct wined3d_color_key *)&desc->ddckCKSrcOverlay); 05603 } 05604 if (desc->dwFlags & DDSD_CKSRCBLT) 05605 { 05606 wined3d_surface_set_color_key(surface->wined3d_surface, DDCKEY_SRCBLT, 05607 (struct wined3d_color_key *)&desc->ddckCKSrcBlt); 05608 } 05609 if (desc->dwFlags & DDSD_LPSURFACE) 05610 { 05611 hr = wined3d_surface_set_mem(surface->wined3d_surface, desc->lpSurface); 05612 if (FAILED(hr)) 05613 { 05614 ERR("Failed to set surface memory, hr %#x.\n", hr); 05615 wined3d_surface_decref(surface->wined3d_surface); 05616 return hr; 05617 } 05618 } 05619 05620 return DD_OK; 05621 } Generated on Sat May 26 2012 04:20:38 for ReactOS by
1.7.6.1
|