Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygencreatesurface.c
Go to the documentation of this file.
00001 /* $Id$ 00002 * 00003 * COPYRIGHT: See COPYING in the top level directory 00004 * PROJECT: ReactOS DirectX 00005 * FILE: ddraw/surface/createsurface.c 00006 * PURPOSE: IDirectDrawSurface Creation 00007 * PROGRAMMER: Magnus Olsen 00008 * 00009 */ 00010 #include "rosdraw.h" 00011 00012 /* 00013 * All parameters must have been checked if they are valid before they are passed to Internal_CreateSurface. 00014 * If not please fix the code in the functions which call Internal_CreateSurface. 00015 * ppSurf,pDDSD,pDDraw are being validated in Internal_CreateSurface. 00016 */ 00017 00018 HRESULT 00019 Internal_CreateSurface( LPDDRAWI_DIRECTDRAW_INT pDDraw, LPDDSURFACEDESC2 pDDSD, 00020 LPDDRAWI_DDRAWSURFACE_INT *ppSurf, IUnknown *pUnkOuter) 00021 { 00022 DDHAL_CANCREATESURFACEDATA mDdCanCreateSurface = { 0 }; 00023 DDHAL_CREATESURFACEDATA mDdCreateSurface = { 0 }; 00024 00025 LPDDRAWI_DDRAWSURFACE_INT ThisSurfInt; 00026 LPDDRAWI_DDRAWSURFACE_LCL ThisSurfLcl; 00027 LPDDRAWI_DDRAWSURFACE_GBL ThisSurfGbl; 00028 LPDDRAWI_DDRAWSURFACE_MORE ThisSurfMore; 00029 00030 LPDDRAWI_DDRAWSURFACE_INT * slist_int = NULL; 00031 LPDDRAWI_DDRAWSURFACE_LCL * slist_lcl = NULL; 00032 LPDDRAWI_DDRAWSURFACE_GBL * slist_gbl = NULL; 00033 LPDDRAWI_DDRAWSURFACE_MORE * slist_more = NULL; 00034 DWORD num_of_surf=1; 00035 DWORD count; 00036 HRESULT ret; 00037 00038 if((pDDraw->lpLcl->dwLocalFlags & DDRAWILCL_SETCOOPCALLED) != DDRAWILCL_SETCOOPCALLED) 00039 { 00040 return DDERR_NOCOOPERATIVELEVELSET; 00041 } 00042 00043 if(pUnkOuter) 00044 { 00045 return CLASS_E_NOAGGREGATION; 00046 } 00047 00048 if(!(pDDSD->dwFlags & DDSD_CAPS)) 00049 { 00050 return DDERR_INVALIDPARAMS; 00051 } 00052 if (pDDraw->lpLcl->dwProcessId != GetCurrentProcessId() ) 00053 { 00054 return DDERR_INVALIDOBJECT; 00055 } 00056 00057 if ( ((pDDSD->ddsCaps.dwCaps & DDSCAPS_SYSTEMMEMORY) == DDSCAPS_SYSTEMMEMORY) && 00058 ((pDDSD->ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY) == DDSCAPS_VIDEOMEMORY) ) 00059 { 00060 return DDERR_INVALIDCAPS; 00061 } 00062 00063 if((!(pDDSD->dwFlags & DDSD_HEIGHT) || !(pDDSD->dwFlags & DDSD_WIDTH)) 00064 && !(pDDSD->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)) 00065 { 00066 return DDERR_INVALIDPARAMS; 00067 } 00068 00069 else if(((pDDSD->dwFlags & DDSD_HEIGHT) || (pDDSD->dwFlags & DDSD_WIDTH)) 00070 && (pDDSD->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)) 00071 { 00072 return DDERR_INVALIDPARAMS; 00073 } 00074 00075 /* 00076 * program does not need set the DDSD_LPSURFACE, 00077 * if they forget set it, the ddraw will autoamtic 00078 * set it for system memory. 00079 */ 00080 if ( ((pDDSD->ddsCaps.dwCaps & DDSCAPS_SYSTEMMEMORY) == DDSCAPS_SYSTEMMEMORY) && 00081 ((pDDSD->dwFlags & DDSD_LPSURFACE) != DDSD_LPSURFACE) ) 00082 { 00083 pDDSD->dwFlags = pDDSD->dwFlags | DDSD_LPSURFACE; 00084 } 00085 00086 /* FIXME count how many surfaces we need */ 00087 00088 DxHeapMemAlloc(slist_int, num_of_surf * sizeof( LPDDRAWI_DDRAWSURFACE_INT ) ); 00089 if( slist_int == NULL) 00090 { 00091 ret = DDERR_OUTOFMEMORY; 00092 goto cleanup; 00093 } 00094 00095 DxHeapMemAlloc(slist_lcl, num_of_surf * sizeof( LPDDRAWI_DDRAWSURFACE_LCL ) ); 00096 if( slist_lcl == NULL ) 00097 { 00098 ret = DDERR_OUTOFMEMORY; 00099 goto cleanup; 00100 } 00101 00102 /* keep pointers to all gbl surfs to be able to free them on error */ 00103 DxHeapMemAlloc(slist_gbl, num_of_surf * sizeof( LPDDRAWI_DDRAWSURFACE_GBL ) ); 00104 if( slist_gbl == NULL ) 00105 { 00106 DxHeapMemFree(slist_int); 00107 return DDERR_OUTOFMEMORY; 00108 } 00109 00110 /* keep pointers to all more surfs to be able to free them on error */ 00111 DxHeapMemAlloc(slist_more, num_of_surf * sizeof( LPDDRAWI_DDRAWSURFACE_MORE ) ); 00112 if( slist_more == NULL ) 00113 { 00114 DxHeapMemFree(slist_int); 00115 return DDERR_OUTOFMEMORY; 00116 } 00117 00118 for( count=0; count < num_of_surf; count++ ) 00119 { 00120 /* Allocate the surface interface and needed members */ 00121 DxHeapMemAlloc(ThisSurfInt, sizeof( DDRAWI_DDRAWSURFACE_INT ) ); 00122 if( ThisSurfInt == NULL ) 00123 { 00124 ret = DDERR_OUTOFMEMORY; 00125 goto cleanup; 00126 } 00127 00128 DxHeapMemAlloc(ThisSurfLcl, sizeof( DDRAWI_DDRAWSURFACE_LCL ) ); 00129 if( ThisSurfLcl == NULL ) 00130 { 00131 ret = DDERR_OUTOFMEMORY; 00132 goto cleanup; 00133 } 00134 00135 DxHeapMemAlloc(ThisSurfGbl, sizeof( DDRAWI_DDRAWSURFACE_GBL ) ); 00136 if( ThisSurfGbl == NULL ) 00137 { 00138 ret = DDERR_OUTOFMEMORY; 00139 goto cleanup; 00140 } 00141 00142 DxHeapMemAlloc(ThisSurfMore, sizeof( DDRAWI_DDRAWSURFACE_MORE ) ); 00143 if( ThisSurfMore == NULL ) 00144 { 00145 ret = DDERR_OUTOFMEMORY; 00146 goto cleanup; 00147 } 00148 00149 /* setup lists, really needed are slist_lcl, slist_int 00150 other slists should be released on return */ 00151 00152 slist_int[count] = ThisSurfInt; 00153 slist_lcl[count] = ThisSurfLcl; 00154 slist_gbl[count] = ThisSurfGbl; 00155 slist_more[count] = ThisSurfMore; 00156 00157 /* Start now fill in the member as they shall look like before call to createsurface */ 00158 00159 ThisSurfInt->lpLcl = ThisSurfLcl; 00160 ThisSurfLcl->lpGbl = ThisSurfGbl; 00161 00162 ThisSurfLcl->ddsCaps.dwCaps = pDDSD->ddsCaps.dwCaps; 00163 00164 ThisSurfGbl->lpDD = pDDraw->lpLcl->lpGbl; 00165 ThisSurfGbl->lpDDHandle = pDDraw->lpLcl->lpGbl; 00166 00167 /* FIXME ? */ 00168 ThisSurfGbl->dwGlobalFlags = DDRAWISURFGBL_ISGDISURFACE; 00169 00170 if (pDDSD->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) 00171 { 00172 ThisSurfGbl->wWidth = pDDraw->lpLcl->lpGbl->vmiData.dwDisplayWidth; 00173 ThisSurfGbl->wHeight = pDDraw->lpLcl->lpGbl->vmiData.dwDisplayHeight; 00174 ThisSurfGbl->lPitch = pDDraw->lpLcl->lpGbl->vmiData.lDisplayPitch; 00175 ThisSurfGbl->dwLinearSize = pDDraw->lpLcl->lpGbl->vmiData.lDisplayPitch; 00176 00177 00178 ThisSurfMore->dmiDDrawReserved7.wWidth = pDDraw->lpLcl->lpGbl->vmiData.dwDisplayWidth; 00179 ThisSurfMore->dmiDDrawReserved7.wHeight = pDDraw->lpLcl->lpGbl->vmiData.dwDisplayHeight; 00180 ThisSurfMore->dmiDDrawReserved7.wBPP = pDDraw->lpLcl->lpGbl->dwMonitorFrequency; 00181 00182 /* FIXME ThisSurfaceMore->dmiDDrawReserved7.wMonitorsAttachedToDesktop */ 00183 ThisSurfMore->dmiDDrawReserved7.wMonitorsAttachedToDesktop = 1; 00184 pDDraw->lpLcl->lpPrimary = ThisSurfInt; 00185 } 00186 else 00187 { 00188 ThisSurfGbl->wWidth = (WORD)pDDSD->dwWidth; 00189 ThisSurfGbl->wHeight = (WORD)pDDSD->dwHeight; 00190 ThisSurfGbl->lPitch = pDDSD->lPitch; 00191 ThisSurfGbl->dwLinearSize = pDDSD->lPitch; 00192 } 00193 00194 if(pDDraw->lpVtbl == &DirectDraw7_Vtable) 00195 { 00196 ThisSurfInt->lpVtbl = &DirectDrawSurface7_Vtable; 00197 } 00198 else if(pDDraw->lpVtbl == &DirectDraw4_Vtable) 00199 { 00200 ThisSurfInt->lpVtbl = &DirectDrawSurface4_Vtable; 00201 } 00202 else if(pDDraw->lpVtbl == &DirectDraw2_Vtable) 00203 { 00204 ThisSurfInt->lpVtbl = &DirectDrawSurface2_Vtable; 00205 } 00206 else if(pDDraw->lpVtbl == &DirectDraw_Vtable) 00207 { 00208 ThisSurfInt->lpVtbl = &DirectDrawSurface_Vtable; 00209 } 00210 else 00211 { 00212 ret = DDERR_NOTINITIALIZED; 00213 goto cleanup; 00214 } 00215 00216 ThisSurfLcl->lpSurfMore = ThisSurfMore; 00217 ThisSurfMore->dwSize = sizeof(DDRAWI_DDRAWSURFACE_MORE); 00218 ThisSurfMore->lpDD_int = pDDraw; 00219 ThisSurfMore->lpDD_lcl = pDDraw->lpLcl; 00220 ThisSurfMore->slist = slist_lcl; 00221 00222 ThisSurfLcl->dwProcessId = GetCurrentProcessId(); 00223 00224 /* FIXME the lpLnk */ 00225 00226 Main_DDrawSurface_AddRef(ThisSurfInt); 00227 } 00228 00229 pDDraw->lpLcl->lpGbl->dsList = (LPDDRAWI_DDRAWSURFACE_INT) slist_int; 00230 00231 /* Fixme call on DdCanCreate then on DdCreateSurface createsurface data here */ 00232 00233 /* FIXME bIsDifferentPixelFormat being set to true or false with automatic detcitons */ 00234 mDdCanCreateSurface.bIsDifferentPixelFormat = FALSE; 00235 00236 mDdCanCreateSurface.lpDD = pDDraw->lpLcl->lpGbl; 00237 mDdCanCreateSurface.CanCreateSurface = pDDraw->lpLcl->lpDDCB->HALDD.CanCreateSurface; 00238 mDdCanCreateSurface.lpDDSurfaceDesc = (LPDDSURFACEDESC) pDDSD; 00239 mDdCanCreateSurface.ddRVal = DDERR_GENERIC; 00240 00241 if (mDdCanCreateSurface.CanCreateSurface(&mDdCanCreateSurface) == DDHAL_DRIVER_NOTHANDLED) 00242 { 00243 DX_STUB_str("mDdCanCreateSurface failed with DDHAL_DRIVER_NOTHANDLED."); 00244 ret = DDERR_NOTINITIALIZED; 00245 goto cleanup; 00246 } 00247 00248 if (mDdCanCreateSurface.ddRVal != DD_OK) 00249 { 00250 DX_STUB_str("mDdCanCreateSurface failed."); 00251 ret = mDdCanCreateSurface.ddRVal; 00252 goto cleanup; 00253 } 00254 00255 mDdCreateSurface.lpDD = pDDraw->lpLcl->lpGbl; 00256 mDdCreateSurface.CreateSurface = pDDraw->lpLcl->lpGbl->lpDDCBtmp->HALDD.CreateSurface; 00257 mDdCreateSurface.ddRVal = DDERR_GENERIC; 00258 mDdCreateSurface.dwSCnt = num_of_surf; 00259 mDdCreateSurface.lpDDSurfaceDesc = (LPDDSURFACEDESC) pDDSD; 00260 mDdCreateSurface.lplpSList = slist_lcl; 00261 00262 if (mDdCreateSurface.CreateSurface(&mDdCreateSurface) == DDHAL_DRIVER_NOTHANDLED) 00263 { 00264 DX_STUB_str("mDdCreateSurface failed with DDHAL_DRIVER_NOTHANDLED."); 00265 ret = DDERR_NOTINITIALIZED; 00266 goto cleanup; 00267 } 00268 00269 if (mDdCreateSurface.ddRVal != DD_OK) 00270 { 00271 DX_STUB_str("mDdCreateSurface failed."); 00272 ret = mDdCreateSurface.ddRVal; 00273 goto cleanup; 00274 } 00275 00276 /* free unneeded slists */ 00277 if (slist_more != NULL) 00278 DxHeapMemFree(slist_more); 00279 if (slist_gbl != NULL) 00280 DxHeapMemFree(slist_gbl); 00281 00282 *ppSurf = (LPDDRAWI_DDRAWSURFACE_INT) &slist_int[0]->lpVtbl; 00283 00284 return DD_OK; 00285 00286 cleanup: 00287 for(count = 0; count < num_of_surf; count++) 00288 { 00289 if (slist_more[count] != NULL) 00290 DxHeapMemFree(slist_more[count]); 00291 if (slist_gbl[count] != NULL) 00292 DxHeapMemFree(slist_gbl[count]); 00293 if (slist_lcl[count] != NULL) 00294 DxHeapMemFree(slist_lcl[count]); 00295 if (slist_int[count] != NULL) 00296 DxHeapMemFree(slist_int[count]); 00297 } 00298 if (slist_more != NULL) 00299 DxHeapMemFree(slist_more); 00300 if (slist_gbl != NULL) 00301 DxHeapMemFree(slist_gbl); 00302 if (slist_lcl != NULL) 00303 DxHeapMemFree(slist_lcl); 00304 if (slist_int != NULL) 00305 DxHeapMemFree(slist_int); 00306 00307 return ret; 00308 } 00309 00310 00311 00312 void CopyDDSurfDescToDDSurfDesc2(LPDDSURFACEDESC2 dst_pDesc, LPDDSURFACEDESC src_pDesc) 00313 { 00314 RtlZeroMemory(dst_pDesc,sizeof(DDSURFACEDESC2)); 00315 RtlCopyMemory(dst_pDesc,src_pDesc,sizeof(DDSURFACEDESC)); 00316 dst_pDesc->dwSize = sizeof(DDSURFACEDESC2); 00317 } 00318 00319 00320 00321 00322 Generated on Sun May 27 2012 04:21:25 for ReactOS by
1.7.6.1
|