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 + -
显示快捷键?