/* * DD_SurfaceComposition_EnumSurfaceDependencies */ HRESULT DDAPI DD_SurfaceComposition_EnumSurfaceDependencies( LPDIRECTDRAWSURFACECOMPOSITION lpDDSurface, LPVOID lpContext, LPDDENUMSURFACESCALLBACK lpEnumSurfacesCallback ) { LPDDRAWI_DDRAWSURFACE_LCL thisx; LPDDRAWI_DDRAWSURFACE_GBL this; thisx = (LPDDRAWI_DDRAWSURFACE_LCL) lpDDSurface; if( !VALID_DIRECTDRAWSURFACE_PTR( thisx ) ) { return DDERR_INVALIDOBJECT; } if( !VALID_CODE_PTR( lpEnumSurfacesCallback ) ) { return DDERR_INVALIDPARAMS; } this = thisx->lpGbl; ENTER_DDRAW(); if( SURFACE_LOST( thisx ) ) { LEAVE_DDRAW(); return DDERR_SURFACELOST; } LEAVE_DDRAW(); return DDERR_UNSUPPORTED; } /* DD_SurfaceComposition_EnumSurfaceDependencies */
/* * DD_SurfaceComposition_GetCompositionOrder */ HRESULT DDAPI DD_SurfaceComposition_GetCompositionOrder( LPDIRECTDRAWSURFACECOMPOSITION lpDDSurface, LPDWORD lpdwCompositionOrder ) { LPDDRAWI_DDRAWSURFACE_LCL thisx; LPDDRAWI_DDRAWSURFACE_GBL this; thisx = (LPDDRAWI_DDRAWSURFACE_LCL) lpDDSurface; if( !VALID_DIRECTDRAWSURFACE_PTR( thisx ) ) { return DDERR_INVALIDOBJECT; } if( !VALID_DWORD_PTR( lpdwCompositionOrder ) ) { return DDERR_INVALIDPARAMS; } this = thisx->lpGbl; ENTER_DDRAW(); if( SURFACE_LOST( thisx ) ) { LEAVE_DDRAW(); return DDERR_SURFACELOST; } // *lpdwCompositionOrder = this->dwCompositionOrder; LEAVE_DDRAW(); return DDERR_UNSUPPORTED; } /* DD_SurfaceComposition_GetCompositionOrder */
/* * DD_SurfaceComposition_Compose */ HRESULT DDAPI DD_SurfaceComposition_Compose( LPDIRECTDRAWSURFACECOMPOSITION lpDDDestSurface, LPRECT lpDestRect, LPDIRECTDRAWSURFACE lpDDSrcSurface, LPRECT lpSrcRect, DWORD dwFlags, LPDDCOMPOSEFX lpDDComposeFX ) { LPDDRAWI_DIRECTDRAW pdrv; LPDDRAWI_DDRAWSURFACE_LCL this_srcx; LPDDRAWI_DDRAWSURFACE_LCL this_destx; LPDDRAWI_DDRAWSURFACE_GBL this_src; LPDDRAWI_DDRAWSURFACE_GBL this_dest; this_destx = (LPDDRAWI_DDRAWSURFACE_LCL) lpDDDestSurface; this_srcx = (LPDDRAWI_DDRAWSURFACE_LCL) lpDDSrcSurface; if( !VALID_DIRECTDRAWSURFACE_PTR( this_destx ) ) { DPF_ERR( "invalid dest specified") ; return DDERR_INVALIDOBJECT; } this_dest = this_destx->lpGbl; pdrv = this_dest->lpDD; ENTER_DDRAW(); if( this_srcx != NULL ) { if( !VALID_DIRECTDRAWSURFACE_PTR( this_srcx ) ) { DPF_ERR( "Invalid source specified" ); LEAVE_DDRAW(); return DDERR_INVALIDOBJECT; } this_src = this_srcx->lpGbl; if( SURFACE_LOST( this_srcx ) ) { LEAVE_DDRAW(); return DDERR_SURFACELOST; } } else { this_src = NULL; } LEAVE_DDRAW(); return DDERR_UNSUPPORTED; } /* DD_SurfaceComposition_Compose */
/* * DD_SurfaceComposition_DeleteSurfaceDependency */ HRESULT DDAPI DD_SurfaceComposition_DeleteSurfaceDependency( LPDIRECTDRAWSURFACECOMPOSITION lpDDSurface, DWORD dwFlagsForNoGoodFuckingReason, LPDIRECTDRAWSURFACE lpDDSurface2 ) { LPDDRAWI_DDRAWSURFACE_LCL thisx; LPDDRAWI_DDRAWSURFACE_GBL this; LPDDRAWI_DDRAWSURFACE_LCL this2x; LPDDRAWI_DDRAWSURFACE_GBL this2; thisx = (LPDDRAWI_DDRAWSURFACE_LCL) lpDDSurface; if( !VALID_DIRECTDRAWSURFACE_PTR( thisx ) ) { return DDERR_INVALIDOBJECT; } this2x = (LPDDRAWI_DDRAWSURFACE_LCL) lpDDSurface2; if( !VALID_DIRECTDRAWSURFACE_PTR( this2x ) ) { return DDERR_INVALIDOBJECT; } this = thisx->lpGbl; this2 = this2x->lpGbl; ENTER_DDRAW(); if( SURFACE_LOST( thisx ) ) { LEAVE_DDRAW(); return DDERR_SURFACELOST; } if( SURFACE_LOST( this2x ) ) { LEAVE_DDRAW(); return DDERR_SURFACELOST; } LEAVE_DDRAW(); return DDERR_UNSUPPORTED; } /* DD_SurfaceComposition_DeleteSurfaceDependency */
/* * DD_SurfaceComposition_DestUnlock */ HRESULT DDAPI DD_SurfaceComposition_DestUnlock( LPDIRECTDRAWSURFACECOMPOSITION lpDDSurface ) { LPDDRAWI_DDRAWSURFACE_LCL thisx; LPDDRAWI_DDRAWSURFACE_GBL this; thisx = (LPDDRAWI_DDRAWSURFACE_LCL) lpDDSurface; if( !VALID_DIRECTDRAWSURFACE_PTR( thisx ) ) { return DDERR_INVALIDOBJECT; } this = thisx->lpGbl; ENTER_DDRAW(); if( SURFACE_LOST( thisx ) ) { LEAVE_DDRAW(); return DDERR_SURFACELOST; } LEAVE_DDRAW(); return DDERR_UNSUPPORTED; } /* DD_SurfaceComposition_DestUnlock */
/* * DD_SurfaceComposition_AddSurfaceDependency */ HRESULT DDAPI DD_SurfaceComposition_AddSurfaceDependency( LPDIRECTDRAWSURFACECOMPOSITION lpDDSurface, LPDIRECTDRAWSURFACE lpDDSurfaceDep ) { LPDDRAWI_DDRAWSURFACE_LCL thisx; LPDDRAWI_DDRAWSURFACE_LCL this_depx; LPDDRAWI_DDRAWSURFACE_GBL this; LPDDRAWI_DDRAWSURFACE_GBL this_dep; thisx = (LPDDRAWI_DDRAWSURFACE_LCL) lpDDSurface; this_depx = (LPDDRAWI_DDRAWSURFACE_LCL) lpDDSurfaceDep; if( !VALID_DIRECTDRAWSURFACE_PTR( thisx ) ) { return DDERR_INVALIDOBJECT; } if( !VALID_DIRECTDRAWSURFACE_PTR( this_depx ) ) { return DDERR_INVALIDOBJECT; } this = thisx->lpGbl; this_dep = this_depx->lpGbl; ENTER_DDRAW(); if( SURFACE_LOST( thisx ) ) { LEAVE_DDRAW(); return DDERR_SURFACELOST; } if( SURFACE_LOST( this_depx ) ) { LEAVE_DDRAW(); return DDERR_SURFACELOST; } LEAVE_DDRAW(); return DDERR_UNSUPPORTED; } /* DD_SurfaceComposition_AddSurfaceDependency */
/* * DD_Surface_AddRef */ ULONG DDAPI DD_Surface_AddRef( LPDIRECTDRAWSURFACE lpDDSurface ) { LPDDRAWI_DIRECTDRAW_GBL pdrv; LPDDRAWI_DDRAWSURFACE_INT this_int; LPDDRAWI_DDRAWSURFACE_LCL this_lcl; LPDDRAWI_DDRAWSURFACE_GBL this; DWORD rcnt; ENTER_DDRAW(); TRY { /* * validate parms */ this_int = (LPDDRAWI_DDRAWSURFACE_INT) lpDDSurface; if( !VALID_DIRECTDRAWSURFACE_PTR( this_int ) ) { DPF_ERR( "Invalid surface pointer" ); LEAVE_DDRAW(); return 0; } this_lcl = this_int->lpLcl; this = this_lcl->lpGbl; pdrv = this->lpDD; // need to allow lost surfaces #if 0 if( SURFACE_LOST( this_lcl ) ) { LEAVE_DDRAW(); return 0; } #endif } EXCEPT( EXCEPTION_EXECUTE_HANDLER ) { DPF_ERR( "Exception encountered validating parameters" ); LEAVE_DDRAW(); return 0; } /* * If this surface is already being freed, immediately return to * prevent recursion. */ if( this_lcl->dwFlags & DDRAWISURF_ISFREE ) { DPF(3, "Leaving AddRef early to prevent recursion" ); LEAVE_DDRAW(); return 0; } /* * update surface reference count */ this->dwRefCnt++; this_lcl->dwLocalRefCnt++; this_int->dwIntRefCnt++; rcnt = this_lcl->dwLocalRefCnt & ~OBJECT_ISROOT; DPF( 4, "DD_Surface_AddRef, Reference Count: Global = %ld Local = %ld Int = %ld", this->dwRefCnt, rcnt, this_int->dwIntRefCnt ); LEAVE_DDRAW(); return this_int->dwIntRefCnt; } /* DD_Surface_AddRef */
/* * DD_Surface_QueryInterface */ HRESULT DDAPI DD_Surface_QueryInterface( LPDIRECTDRAWSURFACE lpDDSurface, REFIID riid, LPVOID FAR * ppvObj ) { LPDDRAWI_DIRECTDRAW_GBL pdrv; LPDDRAWI_DDRAWSURFACE_INT this_int; LPDDRAWI_DDRAWSURFACE_LCL this_lcl; #ifdef STREAMING LPDDRAWI_DDRAWSURFACE_GBLSTREAMING psurf_streaming; #endif LPDDRAWI_DDRAWSURFACE_GBL this; LPDDRAWI_DIRECTDRAW_LCL pdrv_lcl; LPDDRAWI_DIRECTDRAW_INT pdrv_int; D3DCreateTextProc lpfnD3DCreateTextProc; D3DCreateDeviceProc lpfnD3DCreateDeviceProc; HRESULT rval; IUnknown FAR* lpIUnknown; ENTER_DDRAW(); /* * validate parms */ TRY { this_int = (LPDDRAWI_DDRAWSURFACE_INT) lpDDSurface; if( !VALID_DIRECTDRAWSURFACE_PTR( this_int ) ) { DPF_ERR( "Invalid surface pointer" ); LEAVE_DDRAW(); return DDERR_INVALIDOBJECT; } this_lcl = this_int->lpLcl; if( !VALID_PTR_PTR( ppvObj ) ) { DPF_ERR( "Invalid surface interface pointer" ); LEAVE_DDRAW(); return DDERR_INVALIDPARAMS; } *ppvObj = NULL; if( !VALIDEX_IID_PTR( riid ) ) { DPF_ERR( "Invalid IID pointer" ); LEAVE_DDRAW(); return DDERR_INVALIDPARAMS; } this = this_lcl->lpGbl; pdrv = this->lpDD; pdrv_lcl = this_lcl->lpSurfMore->lpDD_lcl; pdrv_int = this_lcl->lpSurfMore->lpDD_int; } EXCEPT( EXCEPTION_EXECUTE_HANDLER ) { DPF_ERR( "Exception encountered validating parameters" ); LEAVE_DDRAW(); return DDERR_INVALIDPARAMS; } /* * asking for IUnknown? */ if( IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IDirectDrawSurface) ) { /* * Our IUnknown interface is the same as our V1 * interface. We must always return the V1 interface * if IUnknown is requested. */ if( this_int->lpVtbl == &ddSurfaceCallbacks ) *ppvObj = (LPVOID) this_int; else *ppvObj = (LPVOID) getDDSInterface( pdrv, this_int->lpLcl, &ddSurfaceCallbacks ); if( NULL == *ppvObj ) { LEAVE_DDRAW(); return E_NOINTERFACE; } else { DD_Surface_AddRef( *ppvObj ); LEAVE_DDRAW(); return DD_OK; } } /* * asking for IDirectDrawSurface2? */ if( IsEqualIID(riid, &IID_IDirectDrawSurface2) ) { /* * if this is already an IDirectDrawSurface2 interface, just * addref and return */ if( this_int->lpVtbl == (LPVOID) &ddSurface2Callbacks ) *ppvObj = (LPVOID) this_int; else *ppvObj = (LPVOID) getDDSInterface( pdrv, this_int->lpLcl, &ddSurface2Callbacks ); if( NULL == *ppvObj ) { LEAVE_DDRAW(); return E_NOINTERFACE; } else { DD_Surface_AddRef( *ppvObj ); LEAVE_DDRAW(); return DD_OK; } } #ifdef STREAMING /* * asking for IDirectDrawSurfaceStreaming? */ if( IsEqualIID(riid, &IID_IDirectDrawSurfaceStreaming) ) { /* * if this is already an IDirectDrawSurfaceStreaming interface, * just addref and return */ if( this_int->lpVtbl == (LPVOID) &ddSurfaceStreamingCallbacks ) { DD_Surface_AddRef( (LPDIRECTDRAWSURFACE) this_int ); *ppvObj = (LPVOID) this_int; } /* * not an IDirectDrawSurfaceStreaming interface, so we need to * create one */ else { psurf_streaming = NewSurfaceInterface( this_lcl, &ddSurfaceStreamingCallbacks ); if( psurf_streaming == NULL ) { LEAVE_DDRAW(); return DDERR_OUTOFMEMORY; } *ppvObj = (LPVOID) psurf_streaming; } LEAVE_DDRAW(); return DD_OK; } #endif #ifdef COMPOSITION /* * asking for IDirectDrawSurfaceComposition? */ if( IsEqualIID(riid, &IID_IDirectDrawSurfaceComposition) ) { } #endif DPF( 2, "IID not understood by Surface QueryInterface - trying Direct3D" ); /* * We maintain a list of IUnknowns aggregated by each surface. * These IUnknowns are lazily evaluated, i.e., we only create * the underlying aggregated object when someone requests the * the IUnknown via QueryInterface. * * We could just hardcode the Direct3D interfaces, check for * them here and create the appropriate interface but that's * inflexible and we would have to track new interfaces added * to Direct3D (a particularly big problem as there are likely * to be many Direct3DDevice interfaces for different device * types). So instead, we probe Direct3D but trying its create * functions with the IID we have been passed and seeing if * it suceeds or not. */ /* * Do we have an existing aggregated IUnknown for this IID? */ lpIUnknown = FindIUnknown( this_lcl, riid ); if( lpIUnknown == NULL ) { if( !D3D_INITIALIZED( pdrv_lcl ) ) { /* * Direct3D is not yet initialized. Before we can attempt * to query for the texture or device interface we must * initialize it. * * NOTE: Currently if initialization fails for any reason * we fail the QueryInterface() with the error returned * by InitD3D() (which will be E_NOINTERFACE if Direct3D * is not properly installed). If we ever end up aggregating * anything else then this is going to be WRONG as we may * end up failing a query for a completely unrelated * interface just because Direct3D failed to initialize. * Hence, we must rethink this if we end up aggregating * anything else. */ rval = InitD3D( pdrv_int ); if( FAILED( rval ) ) { DPF_ERR( "Could not initialize Direct3D" ); LEAVE_DDRAW(); return rval; } } DDASSERT( D3D_INITIALIZED( pdrv_lcl ) ); /* * No matching interface yet - is it a Direct3D texture IID? */ lpfnD3DCreateTextProc = (D3DCreateTextProc) GetProcAddress( pdrv_lcl->hD3DInstance, D3DCREATETEXTURE_PROCNAME ); if( lpfnD3DCreateTextProc != NULL ) { DPF( 3, "Attempting to create Direct3D Texture interface" ); rval = (*lpfnD3DCreateTextProc)( riid, lpDDSurface, &lpIUnknown, (LPUNKNOWN)lpDDSurface ); if( rval == DD_OK ) { /* * Found the interface. Add it to our list. */ if( InsertIUnknown( this_lcl, riid, lpIUnknown ) == NULL ) { /* * Insufficient memory. Discard the interface and fail. */ DPF_ERR( "Insufficient memory to aggregate the Direct3D Texture interface" ); lpIUnknown->lpVtbl->Release( lpIUnknown ); LEAVE_DDRAW(); return DDERR_OUTOFMEMORY; } } else if ( rval != E_NOINTERFACE ) { /* * The CreateTexture call understood the IID but failed for some * other reason. Fail the QueryInterface. */ DPF_ERR( "Direct3D CreateTexture with valid IID" ); LEAVE_DDRAW(); return rval; } } else { DPF( 1, "Could not locate the Direct3D CreateTexture entry point!" ); } } if( lpIUnknown == NULL ) { /* * Still no matching interface - is it a Direct3D device IID? */ /* * NOTE: Don't need to verify that Direct3D is initialized. If we * got to here it must have been initialized (when we tried the * texture interface). */ DDASSERT( D3D_INITIALIZED( pdrv_lcl ) ); lpfnD3DCreateDeviceProc = (D3DCreateDeviceProc) GetProcAddress( pdrv_lcl->hD3DInstance, D3DCREATEDEVICE_PROCNAME ); if( lpfnD3DCreateDeviceProc != NULL ) { DPF( 3, "Attempting to create Direct3D Device interface" ); rval = (*lpfnD3DCreateDeviceProc)( riid, pdrv_lcl->pD3DIUnknown, lpDDSurface, &lpIUnknown, (LPUNKNOWN)lpDDSurface ); if( rval == DD_OK ) { /* * Found the interface. Add it to our list. */ if( InsertIUnknown( this_lcl, riid, lpIUnknown ) == NULL ) { /* * Insufficient memory. Discard the interface and fail. */ DPF_ERR( "Insufficient memory to aggregate the Direct3D Device interface" ); lpIUnknown->lpVtbl->Release( lpIUnknown ); LEAVE_DDRAW(); return DDERR_OUTOFMEMORY; } } else if ( rval != E_NOINTERFACE ) { /* * The CreateDevice call understood the IID but failed for some * other reason. Fail the QueryInterface. */ DPF_ERR( "Direct3D CreateDevice with valid IID" ); LEAVE_DDRAW(); return rval; } } else { DPF( 1, "Could not locate the Direct3D CreateDevice entry point!" ); } } if( lpIUnknown != NULL ) { /* * We have found an aggregated IID - pass the QueryInterface off * on to it. */ DPF( 3, "Passing query to aggregated (Direct3D) interface" ); rval = lpIUnknown->lpVtbl->QueryInterface( lpIUnknown, riid, ppvObj ); if( rval == DD_OK ) { DPF( 3, "Aggregated (Direct3D) QueryInterface successful" ); LEAVE_DDRAW(); return DD_OK; } } DPF_ERR( "IID not understood by DirectDraw" ); LEAVE_DDRAW(); return E_NOINTERFACE; } /* DD_Surface_QueryInterface */
/* * DD_Surface_Release * * Done with a surface. if no one else is using it, then we can free it. */ ULONG DDAPI DD_Surface_Release( LPDIRECTDRAWSURFACE lpDDSurface ) { LPDDRAWI_DDRAWSURFACE_INT this_int; LPDDRAWI_DDRAWSURFACE_LCL this_lcl; DWORD rc; LPDDRAWI_DIRECTDRAW_GBL pdrv; LPDDRAWI_DDRAWSURFACE_INT pparentsurf_int; ENTER_DDRAW(); TRY { this_int = (LPDDRAWI_DDRAWSURFACE_INT) lpDDSurface; if( !VALID_DIRECTDRAWSURFACE_PTR( this_int ) ) { DPF_ERR( "Invalid surface pointer" ); LEAVE_DDRAW(); return 0; } this_lcl = this_int->lpLcl; pdrv = this_lcl->lpGbl->lpDD; } EXCEPT( EXCEPTION_EXECUTE_HANDLER ) { DPF_ERR( "Exception encountered validating parameters" ); LEAVE_DDRAW(); return 0; } /* * If this surface is already being freed, immediately return to * prevent recursion. */ if( this_lcl->dwFlags & DDRAWISURF_ISFREE ) { DPF(3, "Leaving Release early to prevent recursion" ); LEAVE_DDRAW(); return 0; } /* * If this surface is part of a mip-map chain then we will need * to update its parent map's mip-map count. */ pparentsurf_int = NULL; if( this_lcl->ddsCaps.dwCaps & DDSCAPS_MIPMAP ) pparentsurf_int = FindParentMipMap( this_int ); rc = InternalSurfaceRelease( this_int ); /* * Update the parent's mip-map count if necessary * (if the surface really has gone and if the mip-map * has a parent). */ if( ( rc == 0UL ) && ( pparentsurf_int != NULL ) ) UpdateMipMapCount( pparentsurf_int ); LEAVE_DDRAW(); return rc; } /* DD_Surface_Release */