3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS DirectX
5 * FILE: ddraw/surface/createsurface.c
6 * PURPOSE: IDirectDrawSurface Creation
7 * PROGRAMMER: Magnus Olsen
13 * All parameters must have been checked if they are valid before they are passed to Internal_CreateSurface.
14 * If not please fix the code in the functions which call Internal_CreateSurface.
15 * ppSurf,pDDSD,pDDraw are being validated in Internal_CreateSurface.
19 Internal_CreateSurface( LPDDRAWI_DIRECTDRAW_INT pDDraw
, LPDDSURFACEDESC2 pDDSD
,
20 LPDDRAWI_DDRAWSURFACE_INT
*ppSurf
, IUnknown
*pUnkOuter
)
22 DDHAL_CANCREATESURFACEDATA mDdCanCreateSurface
= { 0 };
23 DDHAL_CREATESURFACEDATA mDdCreateSurface
= { 0 };
25 LPDDRAWI_DDRAWSURFACE_INT ThisSurfInt
;
26 LPDDRAWI_DDRAWSURFACE_LCL ThisSurfLcl
;
27 LPDDRAWI_DDRAWSURFACE_GBL ThisSurfGbl
;
28 LPDDRAWI_DDRAWSURFACE_MORE ThisSurfMore
;
30 LPDDRAWI_DDRAWSURFACE_INT
* slist_int
= NULL
;
31 LPDDRAWI_DDRAWSURFACE_LCL
* slist_lcl
= NULL
;
32 LPDDRAWI_DDRAWSURFACE_GBL
* slist_gbl
= NULL
;
33 LPDDRAWI_DDRAWSURFACE_MORE
* slist_more
= NULL
;
38 if((pDDraw
->lpLcl
->dwLocalFlags
& DDRAWILCL_SETCOOPCALLED
) != DDRAWILCL_SETCOOPCALLED
)
40 return DDERR_NOCOOPERATIVELEVELSET
;
45 return CLASS_E_NOAGGREGATION
;
48 if(!(pDDSD
->dwFlags
& DDSD_CAPS
))
50 return DDERR_INVALIDPARAMS
;
52 if (pDDraw
->lpLcl
->dwProcessId
!= GetCurrentProcessId() )
54 return DDERR_INVALIDOBJECT
;
57 if ( ((pDDSD
->ddsCaps
.dwCaps
& DDSCAPS_SYSTEMMEMORY
) == DDSCAPS_SYSTEMMEMORY
) &&
58 ((pDDSD
->ddsCaps
.dwCaps
& DDSCAPS_VIDEOMEMORY
) == DDSCAPS_VIDEOMEMORY
) )
60 return DDERR_INVALIDCAPS
;
63 if((!(pDDSD
->dwFlags
& DDSD_HEIGHT
) || !(pDDSD
->dwFlags
& DDSD_WIDTH
))
64 && !(pDDSD
->ddsCaps
.dwCaps
& DDSCAPS_PRIMARYSURFACE
))
66 return DDERR_INVALIDPARAMS
;
69 else if(((pDDSD
->dwFlags
& DDSD_HEIGHT
) || (pDDSD
->dwFlags
& DDSD_WIDTH
))
70 && (pDDSD
->ddsCaps
.dwCaps
& DDSCAPS_PRIMARYSURFACE
))
72 return DDERR_INVALIDPARAMS
;
76 * program does not need set the DDSD_LPSURFACE,
77 * if they forget set it, the ddraw will autoamtic
78 * set it for system memory.
80 if ( ((pDDSD
->ddsCaps
.dwCaps
& DDSCAPS_SYSTEMMEMORY
) == DDSCAPS_SYSTEMMEMORY
) &&
81 ((pDDSD
->dwFlags
& DDSD_LPSURFACE
) != DDSD_LPSURFACE
) )
83 pDDSD
->dwFlags
= pDDSD
->dwFlags
| DDSD_LPSURFACE
;
86 /* FIXME count how many surfaces we need */
88 DxHeapMemAlloc(slist_int
, num_of_surf
* sizeof( LPDDRAWI_DDRAWSURFACE_INT
) );
89 if( slist_int
== NULL
)
91 ret
= DDERR_OUTOFMEMORY
;
95 DxHeapMemAlloc(slist_lcl
, num_of_surf
* sizeof( LPDDRAWI_DDRAWSURFACE_LCL
) );
96 if( slist_lcl
== NULL
)
98 ret
= DDERR_OUTOFMEMORY
;
102 /* keep pointers to all gbl surfs to be able to free them on error */
103 DxHeapMemAlloc(slist_gbl
, num_of_surf
* sizeof( LPDDRAWI_DDRAWSURFACE_GBL
) );
104 if( slist_gbl
== NULL
)
106 DxHeapMemFree(slist_int
);
107 return DDERR_OUTOFMEMORY
;
110 /* keep pointers to all more surfs to be able to free them on error */
111 DxHeapMemAlloc(slist_more
, num_of_surf
* sizeof( LPDDRAWI_DDRAWSURFACE_MORE
) );
112 if( slist_more
== NULL
)
114 DxHeapMemFree(slist_int
);
115 return DDERR_OUTOFMEMORY
;
118 for( count
=0; count
< num_of_surf
; count
++ )
120 /* Allocate the surface interface and needed members */
121 DxHeapMemAlloc(ThisSurfInt
, sizeof( DDRAWI_DDRAWSURFACE_INT
) );
122 if( ThisSurfInt
== NULL
)
124 ret
= DDERR_OUTOFMEMORY
;
128 DxHeapMemAlloc(ThisSurfLcl
, sizeof( DDRAWI_DDRAWSURFACE_LCL
) );
129 if( ThisSurfLcl
== NULL
)
131 ret
= DDERR_OUTOFMEMORY
;
135 DxHeapMemAlloc(ThisSurfGbl
, sizeof( DDRAWI_DDRAWSURFACE_GBL
) );
136 if( ThisSurfGbl
== NULL
)
138 ret
= DDERR_OUTOFMEMORY
;
142 DxHeapMemAlloc(ThisSurfMore
, sizeof( DDRAWI_DDRAWSURFACE_MORE
) );
143 if( ThisSurfMore
== NULL
)
145 ret
= DDERR_OUTOFMEMORY
;
149 /* setup lists, really needed are slist_lcl, slist_int
150 other slists should be released on return */
152 slist_int
[count
] = ThisSurfInt
;
153 slist_lcl
[count
] = ThisSurfLcl
;
154 slist_gbl
[count
] = ThisSurfGbl
;
155 slist_more
[count
] = ThisSurfMore
;
157 /* Start now fill in the member as they shall look like before call to createsurface */
159 ThisSurfInt
->lpLcl
= ThisSurfLcl
;
160 ThisSurfLcl
->lpGbl
= ThisSurfGbl
;
162 ThisSurfLcl
->ddsCaps
.dwCaps
= pDDSD
->ddsCaps
.dwCaps
;
164 ThisSurfGbl
->lpDD
= pDDraw
->lpLcl
->lpGbl
;
165 ThisSurfGbl
->lpDDHandle
= pDDraw
->lpLcl
->lpGbl
;
168 ThisSurfGbl
->dwGlobalFlags
= DDRAWISURFGBL_ISGDISURFACE
;
170 if (pDDSD
->ddsCaps
.dwCaps
& DDSCAPS_PRIMARYSURFACE
)
172 ThisSurfGbl
->wWidth
= pDDraw
->lpLcl
->lpGbl
->vmiData
.dwDisplayWidth
;
173 ThisSurfGbl
->wHeight
= pDDraw
->lpLcl
->lpGbl
->vmiData
.dwDisplayHeight
;
174 ThisSurfGbl
->lPitch
= pDDraw
->lpLcl
->lpGbl
->vmiData
.lDisplayPitch
;
175 ThisSurfGbl
->dwLinearSize
= pDDraw
->lpLcl
->lpGbl
->vmiData
.lDisplayPitch
;
178 ThisSurfMore
->dmiDDrawReserved7
.wWidth
= pDDraw
->lpLcl
->lpGbl
->vmiData
.dwDisplayWidth
;
179 ThisSurfMore
->dmiDDrawReserved7
.wHeight
= pDDraw
->lpLcl
->lpGbl
->vmiData
.dwDisplayHeight
;
180 ThisSurfMore
->dmiDDrawReserved7
.wBPP
= pDDraw
->lpLcl
->lpGbl
->dwMonitorFrequency
;
182 /* FIXME ThisSurfaceMore->dmiDDrawReserved7.wMonitorsAttachedToDesktop */
183 ThisSurfMore
->dmiDDrawReserved7
.wMonitorsAttachedToDesktop
= 1;
184 pDDraw
->lpLcl
->lpPrimary
= ThisSurfInt
;
188 ThisSurfGbl
->wWidth
= (WORD
)pDDSD
->dwWidth
;
189 ThisSurfGbl
->wHeight
= (WORD
)pDDSD
->dwHeight
;
190 ThisSurfGbl
->lPitch
= pDDSD
->lPitch
;
191 ThisSurfGbl
->dwLinearSize
= pDDSD
->lPitch
;
194 if(pDDraw
->lpVtbl
== &DirectDraw7_Vtable
)
196 ThisSurfInt
->lpVtbl
= &DirectDrawSurface7_Vtable
;
198 else if(pDDraw
->lpVtbl
== &DirectDraw4_Vtable
)
200 ThisSurfInt
->lpVtbl
= &DirectDrawSurface4_Vtable
;
202 else if(pDDraw
->lpVtbl
== &DirectDraw2_Vtable
)
204 ThisSurfInt
->lpVtbl
= &DirectDrawSurface2_Vtable
;
206 else if(pDDraw
->lpVtbl
== &DirectDraw_Vtable
)
208 ThisSurfInt
->lpVtbl
= &DirectDrawSurface_Vtable
;
212 ret
= DDERR_NOTINITIALIZED
;
216 ThisSurfLcl
->lpSurfMore
= ThisSurfMore
;
217 ThisSurfMore
->dwSize
= sizeof(DDRAWI_DDRAWSURFACE_MORE
);
218 ThisSurfMore
->lpDD_int
= pDDraw
;
219 ThisSurfMore
->lpDD_lcl
= pDDraw
->lpLcl
;
220 ThisSurfMore
->slist
= slist_lcl
;
222 ThisSurfLcl
->dwProcessId
= GetCurrentProcessId();
224 /* FIXME the lpLnk */
226 Main_DDrawSurface_AddRef(ThisSurfInt
);
229 pDDraw
->lpLcl
->lpGbl
->dsList
= (LPDDRAWI_DDRAWSURFACE_INT
) slist_int
;
231 /* Fixme call on DdCanCreate then on DdCreateSurface createsurface data here */
233 /* FIXME bIsDifferentPixelFormat being set to true or false with automatic detcitons */
234 mDdCanCreateSurface
.bIsDifferentPixelFormat
= FALSE
;
236 mDdCanCreateSurface
.lpDD
= pDDraw
->lpLcl
->lpGbl
;
237 mDdCanCreateSurface
.CanCreateSurface
= pDDraw
->lpLcl
->lpDDCB
->HALDD
.CanCreateSurface
;
238 mDdCanCreateSurface
.lpDDSurfaceDesc
= (LPDDSURFACEDESC
) pDDSD
;
239 mDdCanCreateSurface
.ddRVal
= DDERR_GENERIC
;
241 if (mDdCanCreateSurface
.CanCreateSurface(&mDdCanCreateSurface
) == DDHAL_DRIVER_NOTHANDLED
)
243 DX_STUB_str("mDdCanCreateSurface failed with DDHAL_DRIVER_NOTHANDLED.");
244 ret
= DDERR_NOTINITIALIZED
;
248 if (mDdCanCreateSurface
.ddRVal
!= DD_OK
)
250 DX_STUB_str("mDdCanCreateSurface failed.");
251 ret
= mDdCanCreateSurface
.ddRVal
;
255 mDdCreateSurface
.lpDD
= pDDraw
->lpLcl
->lpGbl
;
256 mDdCreateSurface
.CreateSurface
= pDDraw
->lpLcl
->lpGbl
->lpDDCBtmp
->HALDD
.CreateSurface
;
257 mDdCreateSurface
.ddRVal
= DDERR_GENERIC
;
258 mDdCreateSurface
.dwSCnt
= num_of_surf
;
259 mDdCreateSurface
.lpDDSurfaceDesc
= (LPDDSURFACEDESC
) pDDSD
;
260 mDdCreateSurface
.lplpSList
= slist_lcl
;
262 if (mDdCreateSurface
.CreateSurface(&mDdCreateSurface
) == DDHAL_DRIVER_NOTHANDLED
)
264 DX_STUB_str("mDdCreateSurface failed with DDHAL_DRIVER_NOTHANDLED.");
265 ret
= DDERR_NOTINITIALIZED
;
269 if (mDdCreateSurface
.ddRVal
!= DD_OK
)
271 DX_STUB_str("mDdCreateSurface failed.");
272 ret
= mDdCreateSurface
.ddRVal
;
276 /* free unneeded slists */
277 if (slist_more
!= NULL
)
278 DxHeapMemFree(slist_more
);
279 if (slist_gbl
!= NULL
)
280 DxHeapMemFree(slist_gbl
);
282 *ppSurf
= (LPDDRAWI_DDRAWSURFACE_INT
) &slist_int
[0]->lpVtbl
;
287 for(count
= 0; count
< num_of_surf
; count
++)
289 if (slist_more
[count
] != NULL
)
290 DxHeapMemFree(slist_more
[count
]);
291 if (slist_gbl
[count
] != NULL
)
292 DxHeapMemFree(slist_gbl
[count
]);
293 if (slist_lcl
[count
] != NULL
)
294 DxHeapMemFree(slist_lcl
[count
]);
295 if (slist_int
[count
] != NULL
)
296 DxHeapMemFree(slist_int
[count
]);
298 if (slist_more
!= NULL
)
299 DxHeapMemFree(slist_more
);
300 if (slist_gbl
!= NULL
)
301 DxHeapMemFree(slist_gbl
);
302 if (slist_lcl
!= NULL
)
303 DxHeapMemFree(slist_lcl
);
304 if (slist_int
!= NULL
)
305 DxHeapMemFree(slist_int
);
312 void CopyDDSurfDescToDDSurfDesc2(LPDDSURFACEDESC2 dst_pDesc
, LPDDSURFACEDESC src_pDesc
)
314 RtlZeroMemory(dst_pDesc
,sizeof(DDSURFACEDESC2
));
315 RtlCopyMemory(dst_pDesc
,src_pDesc
,sizeof(DDSURFACEDESC
));
316 dst_pDesc
->dwSize
= sizeof(DDSURFACEDESC2
);