main.c
来自「Wine-20031016」· C语言 代码 · 共 1,349 行 · 第 1/3 页
C
1,349 行
/* DirectDrawSurface base implementation * * Copyright 1997-2000 Marcus Meissner * Copyright 1998-2000 Lionel Ulmer (most of Direct3D stuff) * Copyright 2000-2001 TransGaming Technologies Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */#include "config.h"#include <assert.h>#include <string.h>#define NONAMELESSUNION#define NONAMELESSSTRUCT#include "winerror.h"#include "mesa_private.h"#include "wine/debug.h"#include "ddraw_private.h"#include "dsurface/main.h"#include "ddraw/main.h"#include "dsurface/thunks.h"WINE_DEFAULT_DEBUG_CHANNEL(ddraw);/** Creation/Destruction functions */HRESULTMain_DirectDrawSurface_Construct(IDirectDrawSurfaceImpl *This, IDirectDrawImpl *pDD, const DDSURFACEDESC2 *pDDSD){ TRACE("(%p)->(%p,%p)\n", This, pDD, pDDSD); if (pDDSD != &This->surface_desc) { This->surface_desc.dwSize = sizeof(This->surface_desc); DD_STRUCT_COPY_BYSIZE(&(This->surface_desc),pDDSD); } This->uniqueness_value = 1; /* unchecked */ This->ref = 1; This->local.lpSurfMore = &This->more; This->local.lpGbl = &This->global; This->local.dwProcessId = GetCurrentProcessId(); This->local.dwFlags = 0; /* FIXME */ This->local.ddsCaps.dwCaps = This->surface_desc.ddsCaps.dwCaps; /* FIXME: more local stuff */ This->more.lpDD_lcl = &pDD->local; This->more.ddsCapsEx.dwCaps2 = This->surface_desc.ddsCaps.dwCaps2; This->more.ddsCapsEx.dwCaps3 = This->surface_desc.ddsCaps.dwCaps3; This->more.ddsCapsEx.dwCaps4 = This->surface_desc.ddsCaps.dwCaps4; /* FIXME: more more stuff */ This->gmore = &This->global_more; This->global.u3.lpDD = pDD->local.lpGbl; /* FIXME: more global stuff */ This->final_release = Main_DirectDrawSurface_final_release; This->late_allocate = Main_DirectDrawSurface_late_allocate; This->attach = Main_DirectDrawSurface_attach; This->detach = Main_DirectDrawSurface_detach; This->lock_update = Main_DirectDrawSurface_lock_update; This->unlock_update = Main_DirectDrawSurface_unlock_update; This->lose_surface = Main_DirectDrawSurface_lose_surface; This->set_palette = Main_DirectDrawSurface_set_palette; This->update_palette = Main_DirectDrawSurface_update_palette; This->get_display_window = Main_DirectDrawSurface_get_display_window; This->get_gamma_ramp = Main_DirectDrawSurface_get_gamma_ramp; This->set_gamma_ramp = Main_DirectDrawSurface_set_gamma_ramp; ICOM_INIT_INTERFACE(This, IDirectDrawSurface3, DDRAW_IDDS3_Thunk_VTable); ICOM_INIT_INTERFACE(This, IDirectDrawGammaControl, DDRAW_IDDGC_VTable); /* There is no generic implementation of IDDS7 or texture */ Main_DirectDraw_AddSurface(pDD, This); return DD_OK;}void Main_DirectDrawSurface_final_release(IDirectDrawSurfaceImpl* This){ Main_DirectDraw_RemoveSurface(This->ddraw_owner, This);}HRESULT Main_DirectDrawSurface_late_allocate(IDirectDrawSurfaceImpl* This){ return DD_OK;}static void Main_DirectDrawSurface_Destroy(IDirectDrawSurfaceImpl* This){ if (This->palette) { IDirectDrawPalette_Release(ICOM_INTERFACE(This->palette, IDirectDrawPalette)); This->palette = NULL; } This->final_release(This); if (This->private != This+1) HeapFree(GetProcessHeap(), 0, This->private); if (This->tex_private) HeapFree(GetProcessHeap(), 0, This->tex_private); HeapFree(GetProcessHeap(), 0, This);}void Main_DirectDrawSurface_ForceDestroy(IDirectDrawSurfaceImpl* This){ WARN("destroying surface %p with refcnt %lu\n", This, This->ref); Main_DirectDrawSurface_Destroy(This);}ULONG WINAPI Main_DirectDrawSurface_Release(LPDIRECTDRAWSURFACE7 iface){ ICOM_THIS(IDirectDrawSurfaceImpl, iface); TRACE("(%p)->(): decreasing from %ld\n", This, This->ref); if (--This->ref == 0) { if (This->aux_release) This->aux_release(This->aux_ctx, This->aux_data); Main_DirectDrawSurface_Destroy(This); TRACE("released surface %p\n", This); return 0; } return This->ref;}ULONG WINAPI Main_DirectDrawSurface_AddRef(LPDIRECTDRAWSURFACE7 iface){ ICOM_THIS(IDirectDrawSurfaceImpl, iface); TRACE("(%p)->(): increasing from %ld\n", This, This->ref); return ++This->ref;}HRESULT WINAPIMain_DirectDrawSurface_QueryInterface(LPDIRECTDRAWSURFACE7 iface, REFIID riid, LPVOID* ppObj){ ICOM_THIS(IDirectDrawSurfaceImpl, iface); TRACE("(%p)->(%s,%p)\n", This, debugstr_guid(riid), ppObj); *ppObj = NULL; if (IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IDirectDrawSurface7, riid) || IsEqualGUID(&IID_IDirectDrawSurface4, riid)) { This->ref++; *ppObj = ICOM_INTERFACE(This, IDirectDrawSurface7); return S_OK; } else if (IsEqualGUID(&IID_IDirectDrawSurface, riid) || IsEqualGUID(&IID_IDirectDrawSurface2, riid) || IsEqualGUID(&IID_IDirectDrawSurface3, riid)) { This->ref++; *ppObj = ICOM_INTERFACE(This, IDirectDrawSurface3); return S_OK; } else if (IsEqualGUID(&IID_IDirectDrawGammaControl, riid)) { This->ref++; *ppObj = ICOM_INTERFACE(This, IDirectDrawGammaControl); return S_OK; }#ifdef HAVE_OPENGL /* interfaces following here require OpenGL */ if( !opengl_initialized ) return E_NOINTERFACE; if ( IsEqualGUID( &IID_D3DDEVICE_OpenGL, riid ) || IsEqualGUID( &IID_IDirect3DHALDevice, riid) ) { IDirect3DDeviceImpl *d3ddevimpl; HRESULT ret_value; ret_value = d3ddevice_create(&d3ddevimpl, This->ddraw_owner, This); if (FAILED(ret_value)) return ret_value; *ppObj = ICOM_INTERFACE(d3ddevimpl, IDirect3DDevice); TRACE(" returning Direct3DDevice interface at %p.\n", *ppObj); This->ref++; /* No idea if this is correct.. Need to check using real Windows */ return ret_value; } else if (IsEqualGUID( &IID_IDirect3DTexture, riid ) || IsEqualGUID( &IID_IDirect3DTexture2, riid )) { HRESULT ret_value = S_OK; /* Note: this is not exactly how Windows does it... But this seems not to hurt the only application I know creating a texture without this flag set and it will prevent bugs in other parts of Wine. */ This->surface_desc.ddsCaps.dwCaps |= DDSCAPS_TEXTURE; /* In case the texture surface was created before the D3D creation */ if (This->tex_private == NULL) { if (This->ddraw_owner->d3d_private == NULL) { ERR("Texture created with no D3D object yet.. Not supported !\n"); return E_NOINTERFACE; } ret_value = This->ddraw_owner->d3d_create_texture(This->ddraw_owner, This, FALSE, This->mip_main); if (FAILED(ret_value)) return ret_value; } if (IsEqualGUID( &IID_IDirect3DTexture, riid )) { *ppObj = ICOM_INTERFACE(This, IDirect3DTexture); TRACE(" returning Direct3DTexture interface at %p.\n", *ppObj); } else { *ppObj = ICOM_INTERFACE(This, IDirect3DTexture2); TRACE(" returning Direct3DTexture2 interface at %p.\n", *ppObj); } This->ref++; return ret_value; }#endif return E_NOINTERFACE;}/*** Callbacks */BOOLMain_DirectDrawSurface_attach(IDirectDrawSurfaceImpl *This, IDirectDrawSurfaceImpl *to){ return TRUE;}BOOL Main_DirectDrawSurface_detach(IDirectDrawSurfaceImpl *This){ return TRUE;}voidMain_DirectDrawSurface_lock_update(IDirectDrawSurfaceImpl* This, LPCRECT pRect, DWORD dwFlags){}voidMain_DirectDrawSurface_unlock_update(IDirectDrawSurfaceImpl* This, LPCRECT pRect){}voidMain_DirectDrawSurface_lose_surface(IDirectDrawSurfaceImpl* This){}voidMain_DirectDrawSurface_set_palette(IDirectDrawSurfaceImpl* This, IDirectDrawPaletteImpl* pal){}voidMain_DirectDrawSurface_update_palette(IDirectDrawSurfaceImpl* This, IDirectDrawPaletteImpl* pal, DWORD dwStart, DWORD dwCount, LPPALETTEENTRY palent){}HWNDMain_DirectDrawSurface_get_display_window(IDirectDrawSurfaceImpl* This){ return 0;}HRESULTMain_DirectDrawSurface_get_gamma_ramp(IDirectDrawSurfaceImpl* This, DWORD dwFlags, LPDDGAMMARAMP lpGammaRamp){ HDC hDC; HRESULT hr; hr = This->get_dc(This, &hDC); if (FAILED(hr)) return hr; hr = GetDeviceGammaRamp(hDC, lpGammaRamp) ? DD_OK : DDERR_UNSUPPORTED; This->release_dc(This, hDC); return hr;}HRESULTMain_DirectDrawSurface_set_gamma_ramp(IDirectDrawSurfaceImpl* This, DWORD dwFlags, LPDDGAMMARAMP lpGammaRamp){ HDC hDC; HRESULT hr; hr = This->get_dc(This, &hDC); if (FAILED(hr)) return hr; hr = SetDeviceGammaRamp(hDC, lpGammaRamp) ? DD_OK : DDERR_UNSUPPORTED; This->release_dc(This, hDC); return hr;}/*** Interface functions */HRESULT WINAPIMain_DirectDrawSurface_AddAttachedSurface(LPDIRECTDRAWSURFACE7 iface, LPDIRECTDRAWSURFACE7 pAttach){ ICOM_THIS(IDirectDrawSurfaceImpl, iface); IDirectDrawSurfaceImpl* surf = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, pAttach); TRACE("(%p)->(%p)\n",This,pAttach); /* Does windows check this? */ if (surf == This) return DDERR_CANNOTATTACHSURFACE; /* unchecked */ /* Does windows check this? */ if (surf->ddraw_owner != This->ddraw_owner) return DDERR_CANNOTATTACHSURFACE; /* unchecked */ if (surf->surface_owner != NULL) return DDERR_SURFACEALREADYATTACHED; /* unchecked */ /* TODO MSDN: "You can attach only z-buffer surfaces with this method." * But apparently backbuffers and mipmaps can be attached too. */ /* Set MIPMAPSUBLEVEL if this seems to be one */ if (This->surface_desc.ddsCaps.dwCaps & surf->surface_desc.ddsCaps.dwCaps & DDSCAPS_MIPMAP) { surf->surface_desc.ddsCaps.dwCaps2 |= DDSCAPS2_MIPMAPSUBLEVEL; /* FIXME: we should probably also add to dwMipMapCount of this * and all parent surfaces (update create_texture if you do) */ } /* Callback to allow the surface to do something special now that it is * attached. (e.g. maybe the Z-buffer tells the renderer to use it.) */ if (!surf->attach(surf, This)) return DDERR_CANNOTATTACHSURFACE; /* check: Where should it go in the chain? This puts it on the head. */ if (This->attached) This->attached->prev_attached = surf; surf->next_attached = This->attached; surf->prev_attached = NULL; This->attached = surf; surf->surface_owner = This; IDirectDrawSurface7_AddRef(pAttach); return DD_OK;}/* MSDN: "not currently implemented." */HRESULT WINAPIMain_DirectDrawSurface_AddOverlayDirtyRect(LPDIRECTDRAWSURFACE7 iface, LPRECT pRect){ TRACE("(%p)->(%p)\n",iface,pRect); return DDERR_UNSUPPORTED; /* unchecked */}/* MSDN: "not currently implemented." */HRESULT WINAPIMain_DirectDrawSurface_BltBatch(LPDIRECTDRAWSURFACE7 iface, LPDDBLTBATCH pBatch, DWORD dwCount, DWORD dwFlags){ TRACE("(%p)->(%p,%ld,%08lx)\n",iface,pBatch,dwCount,dwFlags); return DDERR_UNSUPPORTED; /* unchecked */}HRESULT WINAPIMain_DirectDrawSurface_ChangeUniquenessValue(LPDIRECTDRAWSURFACE7 iface){ ICOM_THIS(IDirectDrawSurfaceImpl, iface); volatile IDirectDrawSurfaceImpl* vThis = This; TRACE("(%p)\n",This); /* A uniquness value of 0 is apparently special. * This needs to be checked. */ while (1) { DWORD old_uniqueness_value = vThis->uniqueness_value; DWORD new_uniqueness_value = old_uniqueness_value+1; if (old_uniqueness_value == 0) break; if (new_uniqueness_value == 0) new_uniqueness_value = 1; if (InterlockedCompareExchange((LONG*)&vThis->uniqueness_value, old_uniqueness_value, new_uniqueness_value) == old_uniqueness_value) break; } return DD_OK;}HRESULT WINAPIMain_DirectDrawSurface_DeleteAttachedSurface(LPDIRECTDRAWSURFACE7 iface, DWORD dwFlags, LPDIRECTDRAWSURFACE7 pAttach){ ICOM_THIS(IDirectDrawSurfaceImpl, iface); IDirectDrawSurfaceImpl* surf = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, pAttach); TRACE("(%p)->(%08lx,%p)\n",This,dwFlags,pAttach); if (!surf || (surf->surface_owner != This)) return DDERR_SURFACENOTATTACHED; /* unchecked */ surf->detach(surf); /* Remove MIPMAPSUBLEVEL if this seemed to be one */ if (This->surface_desc.ddsCaps.dwCaps & surf->surface_desc.ddsCaps.dwCaps & DDSCAPS_MIPMAP) { surf->surface_desc.ddsCaps.dwCaps2 &= ~DDSCAPS2_MIPMAPSUBLEVEL; /* FIXME: we should probably also subtract from dwMipMapCount of this * and all parent surfaces */ } if (surf->next_attached) surf->next_attached->prev_attached = surf->prev_attached; if (surf->prev_attached) surf->prev_attached->next_attached = surf->next_attached; if (This->attached == surf) This->attached = surf->next_attached; IDirectDrawSurface7_Release(pAttach); return DD_OK;}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?