2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS DirectX
4 * FILE: dll/directx/ddraw/Surface/createsurface.c
5 * PURPOSE: IDirectDrawSurface Creation
6 * PROGRAMMER: Magnus Olsen
12 * All parameters must have been checked if they are valid before they are passed to Internal_CreateSurface.
13 * If not please fix the code in the functions which call Internal_CreateSurface.
14 * ppSurf,pDDSD,pDDraw are being validated in Internal_CreateSurface.
18 Internal_CreateSurface( LPDDRAWI_DIRECTDRAW_INT pDDraw
, LPDDSURFACEDESC2 pDDSD
,
19 LPDDRAWI_DDRAWSURFACE_INT
*ppSurf
, IUnknown
*pUnkOuter
)
21 DDHAL_CANCREATESURFACEDATA mDdCanCreateSurface
= { 0 };
22 DDHAL_CREATESURFACEDATA mDdCreateSurface
= { 0 };
24 LPDDRAWI_DDRAWSURFACE_INT ThisSurfInt
;
25 LPDDRAWI_DDRAWSURFACE_LCL ThisSurfLcl
;
26 LPDDRAWI_DDRAWSURFACE_GBL ThisSurfGbl
;
27 LPDDRAWI_DDRAWSURFACE_MORE ThisSurfMore
;
29 LPDDRAWI_DDRAWSURFACE_INT
* slist_int
= NULL
;
30 LPDDRAWI_DDRAWSURFACE_LCL
* slist_lcl
= NULL
;
31 LPDDRAWI_DDRAWSURFACE_GBL
* slist_gbl
= NULL
;
32 LPDDRAWI_DDRAWSURFACE_MORE
* slist_more
= NULL
;
37 if((pDDraw
->lpLcl
->dwLocalFlags
& DDRAWILCL_SETCOOPCALLED
) != DDRAWILCL_SETCOOPCALLED
)
39 return DDERR_NOCOOPERATIVELEVELSET
;
44 return CLASS_E_NOAGGREGATION
;
47 if(!(pDDSD
->dwFlags
& DDSD_CAPS
))
49 return DDERR_INVALIDPARAMS
;
51 if (pDDraw
->lpLcl
->dwProcessId
!= GetCurrentProcessId() )
53 return DDERR_INVALIDOBJECT
;
56 if ( ((pDDSD
->ddsCaps
.dwCaps
& DDSCAPS_SYSTEMMEMORY
) == DDSCAPS_SYSTEMMEMORY
) &&
57 ((pDDSD
->ddsCaps
.dwCaps
& DDSCAPS_VIDEOMEMORY
) == DDSCAPS_VIDEOMEMORY
) )
59 return DDERR_INVALIDCAPS
;
62 if((!(pDDSD
->dwFlags
& DDSD_HEIGHT
) || !(pDDSD
->dwFlags
& DDSD_WIDTH
))
63 && !(pDDSD
->ddsCaps
.dwCaps
& DDSCAPS_PRIMARYSURFACE
))
65 return DDERR_INVALIDPARAMS
;
68 else if(((pDDSD
->dwFlags
& DDSD_HEIGHT
) || (pDDSD
->dwFlags
& DDSD_WIDTH
))
69 && (pDDSD
->ddsCaps
.dwCaps
& DDSCAPS_PRIMARYSURFACE
))
71 return DDERR_INVALIDPARAMS
;
75 * program does not need set the DDSD_LPSURFACE,
76 * if they forget set it, the ddraw will autoamtic
77 * set it for system memory.
79 if ( ((pDDSD
->ddsCaps
.dwCaps
& DDSCAPS_SYSTEMMEMORY
) == DDSCAPS_SYSTEMMEMORY
) &&
80 ((pDDSD
->dwFlags
& DDSD_LPSURFACE
) != DDSD_LPSURFACE
) )
82 pDDSD
->dwFlags
= pDDSD
->dwFlags
| DDSD_LPSURFACE
;
85 /* FIXME count how many surfaces we need */
87 DxHeapMemAlloc(slist_int
, num_of_surf
* sizeof( LPDDRAWI_DDRAWSURFACE_INT
) );
88 if( slist_int
== NULL
)
90 ret
= DDERR_OUTOFMEMORY
;
94 DxHeapMemAlloc(slist_lcl
, num_of_surf
* sizeof( LPDDRAWI_DDRAWSURFACE_LCL
) );
95 if( slist_lcl
== NULL
)
97 ret
= DDERR_OUTOFMEMORY
;
101 /* keep pointers to all gbl surfs to be able to free them on error */
102 DxHeapMemAlloc(slist_gbl
, num_of_surf
* sizeof( LPDDRAWI_DDRAWSURFACE_GBL
) );
103 if( slist_gbl
== NULL
)
105 DxHeapMemFree(slist_int
);
106 return DDERR_OUTOFMEMORY
;
109 /* keep pointers to all more surfs to be able to free them on error */
110 DxHeapMemAlloc(slist_more
, num_of_surf
* sizeof( LPDDRAWI_DDRAWSURFACE_MORE
) );
111 if( slist_more
== NULL
)
113 DxHeapMemFree(slist_int
);
114 return DDERR_OUTOFMEMORY
;
117 for( count
=0; count
< num_of_surf
; count
++ )
119 /* Allocate the surface interface and needed members */
120 DxHeapMemAlloc(ThisSurfInt
, sizeof( DDRAWI_DDRAWSURFACE_INT
) );
121 if( ThisSurfInt
== NULL
)
123 ret
= DDERR_OUTOFMEMORY
;
127 DxHeapMemAlloc(ThisSurfLcl
, sizeof( DDRAWI_DDRAWSURFACE_LCL
) );
128 if( ThisSurfLcl
== NULL
)
130 ret
= DDERR_OUTOFMEMORY
;
134 DxHeapMemAlloc(ThisSurfGbl
, sizeof( DDRAWI_DDRAWSURFACE_GBL
) );
135 if( ThisSurfGbl
== NULL
)
137 ret
= DDERR_OUTOFMEMORY
;
141 DxHeapMemAlloc(ThisSurfMore
, sizeof( DDRAWI_DDRAWSURFACE_MORE
) );
142 if( ThisSurfMore
== NULL
)
144 ret
= DDERR_OUTOFMEMORY
;
148 /* setup lists, really needed are slist_lcl, slist_int
149 other slists should be released on return */
151 slist_int
[count
] = ThisSurfInt
;
152 slist_lcl
[count
] = ThisSurfLcl
;
153 slist_gbl
[count
] = ThisSurfGbl
;
154 slist_more
[count
] = ThisSurfMore
;
156 /* Start now fill in the member as they shall look like before call to createsurface */
158 ThisSurfInt
->lpLcl
= ThisSurfLcl
;
159 ThisSurfLcl
->lpGbl
= ThisSurfGbl
;
161 ThisSurfLcl
->ddsCaps
.dwCaps
= pDDSD
->ddsCaps
.dwCaps
;
163 ThisSurfGbl
->lpDD
= pDDraw
->lpLcl
->lpGbl
;
164 ThisSurfGbl
->lpDDHandle
= pDDraw
->lpLcl
->lpGbl
;
167 ThisSurfGbl
->dwGlobalFlags
= DDRAWISURFGBL_ISGDISURFACE
;
169 if (pDDSD
->ddsCaps
.dwCaps
& DDSCAPS_PRIMARYSURFACE
)
171 ThisSurfGbl
->wWidth
= pDDraw
->lpLcl
->lpGbl
->vmiData
.dwDisplayWidth
;
172 ThisSurfGbl
->wHeight
= pDDraw
->lpLcl
->lpGbl
->vmiData
.dwDisplayHeight
;
173 ThisSurfGbl
->lPitch
= pDDraw
->lpLcl
->lpGbl
->vmiData
.lDisplayPitch
;
174 ThisSurfGbl
->dwLinearSize
= pDDraw
->lpLcl
->lpGbl
->vmiData
.lDisplayPitch
;
177 ThisSurfMore
->dmiDDrawReserved7
.wWidth
= pDDraw
->lpLcl
->lpGbl
->vmiData
.dwDisplayWidth
;
178 ThisSurfMore
->dmiDDrawReserved7
.wHeight
= pDDraw
->lpLcl
->lpGbl
->vmiData
.dwDisplayHeight
;
179 ThisSurfMore
->dmiDDrawReserved7
.wBPP
= pDDraw
->lpLcl
->lpGbl
->dwMonitorFrequency
;
181 /* FIXME ThisSurfaceMore->dmiDDrawReserved7.wMonitorsAttachedToDesktop */
182 ThisSurfMore
->dmiDDrawReserved7
.wMonitorsAttachedToDesktop
= 1;
183 pDDraw
->lpLcl
->lpPrimary
= ThisSurfInt
;
187 ThisSurfGbl
->wWidth
= (WORD
)pDDSD
->dwWidth
;
188 ThisSurfGbl
->wHeight
= (WORD
)pDDSD
->dwHeight
;
189 ThisSurfGbl
->lPitch
= pDDSD
->lPitch
;
190 ThisSurfGbl
->dwLinearSize
= pDDSD
->lPitch
;
193 if(pDDraw
->lpVtbl
== &DirectDraw7_Vtable
)
195 ThisSurfInt
->lpVtbl
= &DirectDrawSurface7_Vtable
;
197 else if(pDDraw
->lpVtbl
== &DirectDraw4_Vtable
)
199 ThisSurfInt
->lpVtbl
= &DirectDrawSurface4_Vtable
;
201 else if(pDDraw
->lpVtbl
== &DirectDraw2_Vtable
)
203 ThisSurfInt
->lpVtbl
= &DirectDrawSurface2_Vtable
;
205 else if(pDDraw
->lpVtbl
== &DirectDraw_Vtable
)
207 ThisSurfInt
->lpVtbl
= &DirectDrawSurface_Vtable
;
211 ret
= DDERR_NOTINITIALIZED
;
215 ThisSurfLcl
->lpSurfMore
= ThisSurfMore
;
216 ThisSurfMore
->dwSize
= sizeof(DDRAWI_DDRAWSURFACE_MORE
);
217 ThisSurfMore
->lpDD_int
= pDDraw
;
218 ThisSurfMore
->lpDD_lcl
= pDDraw
->lpLcl
;
219 ThisSurfMore
->slist
= slist_lcl
;
221 ThisSurfLcl
->dwProcessId
= GetCurrentProcessId();
223 /* FIXME the lpLnk */
225 Main_DDrawSurface_AddRef(ThisSurfInt
);
228 pDDraw
->lpLcl
->lpGbl
->dsList
= (LPDDRAWI_DDRAWSURFACE_INT
) slist_int
;
230 /* Fixme call on DdCanCreate then on DdCreateSurface createsurface data here */
232 /* FIXME bIsDifferentPixelFormat being set to true or false with automatic detcitons */
233 mDdCanCreateSurface
.bIsDifferentPixelFormat
= FALSE
;
235 mDdCanCreateSurface
.lpDD
= pDDraw
->lpLcl
->lpGbl
;
236 mDdCanCreateSurface
.CanCreateSurface
= pDDraw
->lpLcl
->lpDDCB
->HALDD
.CanCreateSurface
;
237 mDdCanCreateSurface
.lpDDSurfaceDesc
= (LPDDSURFACEDESC
) pDDSD
;
238 mDdCanCreateSurface
.ddRVal
= DDERR_GENERIC
;
240 if (mDdCanCreateSurface
.CanCreateSurface(&mDdCanCreateSurface
) == DDHAL_DRIVER_NOTHANDLED
)
242 DX_STUB_str("mDdCanCreateSurface failed with DDHAL_DRIVER_NOTHANDLED.");
243 ret
= DDERR_NOTINITIALIZED
;
247 if (mDdCanCreateSurface
.ddRVal
!= DD_OK
)
249 DX_STUB_str("mDdCanCreateSurface failed.");
250 ret
= mDdCanCreateSurface
.ddRVal
;
254 mDdCreateSurface
.lpDD
= pDDraw
->lpLcl
->lpGbl
;
255 mDdCreateSurface
.CreateSurface
= pDDraw
->lpLcl
->lpGbl
->lpDDCBtmp
->HALDD
.CreateSurface
;
256 mDdCreateSurface
.ddRVal
= DDERR_GENERIC
;
257 mDdCreateSurface
.dwSCnt
= num_of_surf
;
258 mDdCreateSurface
.lpDDSurfaceDesc
= (LPDDSURFACEDESC
) pDDSD
;
259 mDdCreateSurface
.lplpSList
= slist_lcl
;
261 if (mDdCreateSurface
.CreateSurface(&mDdCreateSurface
) == DDHAL_DRIVER_NOTHANDLED
)
263 DX_STUB_str("mDdCreateSurface failed with DDHAL_DRIVER_NOTHANDLED.");
264 ret
= DDERR_NOTINITIALIZED
;
268 if (mDdCreateSurface
.ddRVal
!= DD_OK
)
270 DX_STUB_str("mDdCreateSurface failed.");
271 ret
= mDdCreateSurface
.ddRVal
;
275 /* free unneeded slists */
276 if (slist_more
!= NULL
)
277 DxHeapMemFree(slist_more
);
278 if (slist_gbl
!= NULL
)
279 DxHeapMemFree(slist_gbl
);
281 *ppSurf
= (LPDDRAWI_DDRAWSURFACE_INT
) &slist_int
[0]->lpVtbl
;
286 for(count
= 0; count
< num_of_surf
; count
++)
288 if (slist_more
[count
] != NULL
)
289 DxHeapMemFree(slist_more
[count
]);
290 if (slist_gbl
[count
] != NULL
)
291 DxHeapMemFree(slist_gbl
[count
]);
292 if (slist_lcl
[count
] != NULL
)
293 DxHeapMemFree(slist_lcl
[count
]);
294 if (slist_int
[count
] != NULL
)
295 DxHeapMemFree(slist_int
[count
]);
297 if (slist_more
!= NULL
)
298 DxHeapMemFree(slist_more
);
299 if (slist_gbl
!= NULL
)
300 DxHeapMemFree(slist_gbl
);
301 if (slist_lcl
!= NULL
)
302 DxHeapMemFree(slist_lcl
);
303 if (slist_int
!= NULL
)
304 DxHeapMemFree(slist_int
);
311 void CopyDDSurfDescToDDSurfDesc2(LPDDSURFACEDESC2 dst_pDesc
, LPDDSURFACEDESC src_pDesc
)
313 RtlZeroMemory(dst_pDesc
,sizeof(DDSURFACEDESC2
));
314 RtlCopyMemory(dst_pDesc
,src_pDesc
,sizeof(DDSURFACEDESC
));
315 dst_pDesc
->dwSize
= sizeof(DDSURFACEDESC2
);