Fixing a crash, fixed so Setcoparative pass the test, still some werid bugs after...
[reactos.git] / reactos / dll / directx / ddraw / startup.c
1 /* $Id: main.c 21434 2006-04-01 19:12:56Z greatlrd $
2 *
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: lib/ddraw/ddraw.c
6 * PURPOSE: DirectDraw Library
7 * PROGRAMMER: Magnus Olsen (greatlrd)
8 *
9 */
10
11 #include <windows.h>
12 #include "rosdraw.h"
13 #include "d3dhal.h"
14 #include "ddrawgdi.h"
15
16 DDRAWI_DIRECTDRAW_GBL ddgbl;
17 DDRAWI_DDRAWSURFACE_GBL ddSurfGbl;
18
19 WCHAR classname[128];
20 WNDCLASSW wnd_class;
21
22
23
24 HRESULT
25 WINAPI
26 Create_DirectDraw (LPGUID pGUID,
27 LPDIRECTDRAW* pIface,
28 REFIID id,
29 BOOL ex)
30 {
31 LPDDRAWI_DIRECTDRAW_INT This = (LPDDRAWI_DIRECTDRAW_INT)*pIface;
32
33 DX_WINDBG_trace();
34
35 if (This == NULL)
36 {
37 /* We do not have a DirectDraw interface, we need alloc it*/
38 LPDDRAWI_DIRECTDRAW_INT memThis;
39
40 memThis = DxHeapMemAlloc(sizeof(DDRAWI_DIRECTDRAW_INT));
41 This = memThis;
42 if (This == NULL)
43 {
44 if (memThis != NULL)
45 DxHeapMemFree(memThis);
46
47 DX_STUB_str("DDERR_OUTOFMEMORY");
48 return DDERR_OUTOFMEMORY;
49 }
50 }
51 else
52 {
53 /* We got the DirectDraw interface alloc and we need create the link */
54 LPDDRAWI_DIRECTDRAW_INT newThis;
55 newThis = DxHeapMemAlloc(sizeof(DDRAWI_DIRECTDRAW_INT));
56 if (newThis == NULL)
57 {
58 DX_STUB_str("DDERR_OUTOFMEMORY");
59 return DDERR_OUTOFMEMORY;
60 }
61
62 /* we need check the GUID lpGUID what type it is */
63 if (pGUID != (LPGUID)DDCREATE_HARDWAREONLY)
64 {
65 if (pGUID !=NULL)
66 {
67 This = newThis;
68 DX_STUB_str("DDERR_INVALIDDIRECTDRAWGUID");
69 return DDERR_INVALIDDIRECTDRAWGUID;
70 }
71 }
72 newThis->lpLink = This;
73 This = newThis;
74 }
75
76 /* Fixme release memory alloc if we fail */
77 This->lpLcl = DxHeapMemAlloc(sizeof(DDRAWI_DIRECTDRAW_INT));
78 if (This->lpLcl == NULL)
79 {
80 DX_STUB_str("DDERR_OUTOFMEMORY");
81 return DDERR_OUTOFMEMORY;
82 }
83 This->lpLcl->lpGbl = &ddgbl;
84
85 *pIface = (LPDIRECTDRAW)This;
86
87 /* Get right interface we whant */
88 if (Main_DirectDraw_QueryInterface((LPDIRECTDRAW7)This, id, (void**)&pIface) == DD_OK)
89 {
90 DX_STUB_str("Got iface");
91
92 if (StartDirectDraw((LPDIRECTDRAW*)This, pGUID, FALSE) == DD_OK);
93 {
94 DX_STUB_str("here");
95
96 /*
97 RtlZeroMemory(&wnd_class, sizeof(wnd_class));
98 wnd_class.style = CS_HREDRAW | CS_VREDRAW;
99 wnd_class.lpfnWndProc = DefWindowProcW;
100 wnd_class.cbClsExtra = 0;
101 wnd_class.cbWndExtra = 0;
102 wnd_class.hInstance = GetModuleHandleW(0);
103 wnd_class.hIcon = 0;
104 wnd_class.hCursor = 0;
105 wnd_class.hbrBackground = (HBRUSH) GetStockObject(BLACK_BRUSH);
106 wnd_class.lpszMenuName = NULL;
107 wnd_class.lpszClassName = classname;
108 if(!RegisterClassW(&wnd_class))
109 {
110 DX_STUB_str("DDERR_GENERIC");
111 return DDERR_GENERIC;
112 }
113 */
114
115 DX_STUB_str("DD_OK");
116 return DD_OK;
117 }
118 }
119
120 DX_STUB_str("DDERR_INVALIDPARAMS");
121 return DDERR_INVALIDPARAMS;
122 }
123
124
125 HRESULT WINAPI
126 StartDirectDraw(LPDIRECTDRAW* iface, LPGUID lpGuid, BOOL reenable)
127 {
128 LPDDRAWI_DIRECTDRAW_INT This = (LPDDRAWI_DIRECTDRAW_INT)iface;
129 DWORD hal_ret = DD_FALSE;
130 DWORD hel_ret = DD_FALSE;
131 DWORD devicetypes = 0;
132 DWORD dwFlags = 0;
133
134 DX_WINDBG_trace();
135
136
137 /*
138 * ddgbl.dwPDevice is not longer in use in windows 2000 and higher
139 * I am using it for device type
140 * devicetypes = 1 : both hal and hel are enable
141 * devicetypes = 2 : both hal are enable
142 * devicetypes = 3 : both hel are enable
143 * devicetypes = 4 :loading a guid drv from the register
144 */
145
146
147
148 if (reenable == FALSE)
149 {
150 if (This->lpLink == NULL)
151 {
152 RtlZeroMemory(&ddgbl, sizeof(DDRAWI_DIRECTDRAW_GBL));
153 This->lpLcl->lpGbl->dwRefCnt++;
154 if (ddgbl.lpDDCBtmp == NULL)
155 {
156 ddgbl.lpDDCBtmp = (LPDDHAL_CALLBACKS) DxHeapMemAlloc(sizeof(DDHAL_CALLBACKS));
157 if (ddgbl.lpDDCBtmp == NULL)
158 {
159 DX_STUB_str("Out of memmory");
160 return DD_FALSE;
161 }
162 }
163 }
164 }
165
166 DX_STUB_str("here");
167
168 if (reenable == FALSE)
169 {
170 if (lpGuid == NULL)
171 {
172 devicetypes= 1;
173
174 /* Create HDC for default, hal and hel driver */
175 This->lpLcl->hWnd = (ULONG_PTR) GetActiveWindow();
176 This->lpLcl->hDC = (ULONG_PTR) GetDC((HWND)This->lpLcl->hWnd);
177
178 /* cObsolete is undoc in msdn it being use in CreateDCA */
179 RtlCopyMemory(&ddgbl.cObsolete,&"DISPLAY",7);
180 RtlCopyMemory(&ddgbl.cDriverName,&"DISPLAY",7);
181 dwFlags |= DDRAWI_DISPLAYDRV | DDRAWI_GDIDRV;
182 }
183 else if (lpGuid == (LPGUID) DDCREATE_HARDWAREONLY)
184 {
185 devicetypes = 2;
186 /* Create HDC for default, hal driver */
187 This->lpLcl->hWnd =(ULONG_PTR) GetActiveWindow();
188 This->lpLcl->hDC = (ULONG_PTR) GetDC((HWND)This->lpLcl->hWnd);
189
190 /* cObsolete is undoc in msdn it being use in CreateDCA */
191 RtlCopyMemory(&ddgbl.cObsolete,&"DISPLAY",7);
192 RtlCopyMemory(&ddgbl.cDriverName,&"DISPLAY",7);
193 dwFlags |= DDRAWI_DISPLAYDRV | DDRAWI_GDIDRV;
194 }
195 else if (lpGuid == (LPGUID) DDCREATE_EMULATIONONLY)
196 {
197 devicetypes = 3;
198
199 /* Create HDC for default, hal and hel driver */
200 This->lpLcl->hWnd = (ULONG_PTR) GetActiveWindow();
201 This->lpLcl->hDC = (ULONG_PTR) GetDC((HWND)This->lpLcl->hWnd);
202
203 /* cObsolete is undoc in msdn it being use in CreateDCA */
204 RtlCopyMemory(&ddgbl.cObsolete,&"DISPLAY",7);
205 RtlCopyMemory(&ddgbl.cDriverName,&"DISPLAY",7);
206
207 dwFlags |= DDRAWI_DISPLAYDRV | DDRAWI_GDIDRV;
208 }
209 else
210 {
211 /* FIXME : need getting driver from the GUID that have been pass in from
212 * the register. we do not support that yet
213 */
214 devicetypes = 4;
215 This->lpLcl->hDC = (ULONG_PTR) NULL ;
216 This->lpLcl->hWnd = (ULONG_PTR) GetActiveWindow();
217 }
218
219 if ( (HDC)This->lpLcl->hDC == NULL)
220 {
221 DX_STUB_str("DDERR_OUTOFMEMORY");
222 return DDERR_OUTOFMEMORY ;
223 }
224 }
225
226 This->lpLcl->lpDDCB = ddgbl.lpDDCBtmp;
227
228 /* Startup HEL and HAL */
229 This->lpLcl->lpDDCB = This->lpLcl->lpGbl->lpDDCBtmp;
230 This->lpLcl->dwProcessId = GetCurrentProcessId();
231
232 switch (devicetypes)
233 {
234 case 2:
235 hal_ret = StartDirectDrawHal(iface, reenable);
236 This->lpLcl->lpDDCB->HELDD.dwFlags = 0;
237 break;
238
239 case 3:
240 hel_ret = StartDirectDrawHel(iface, reenable);
241 This->lpLcl->lpDDCB->HALDD.dwFlags = 0;
242 break;
243
244 default:
245 hal_ret = StartDirectDrawHal(iface, reenable);
246 hel_ret = StartDirectDrawHel(iface, reenable);
247 }
248
249 if (hal_ret!=DD_OK)
250 {
251 if (hel_ret!=DD_OK)
252 {
253 DX_STUB_str("DDERR_NODIRECTDRAWSUPPORT");
254 return DDERR_NODIRECTDRAWSUPPORT;
255 }
256 dwFlags |= DDRAWI_NOHARDWARE;
257 }
258
259 if (hel_ret!=DD_OK)
260 {
261 dwFlags |= DDRAWI_NOEMULATION;
262
263 }
264 else
265 {
266 dwFlags |= DDRAWI_EMULATIONINITIALIZED;
267 }
268
269 /* Fill some basic info for Surface */
270 This->lpLcl->lpGbl->dwFlags = dwFlags | DDRAWI_ATTACHEDTODESKTOP;
271 This->lpLcl->lpDDCB = This->lpLcl->lpGbl->lpDDCBtmp;
272 This->lpLcl->hDD = This->lpLcl->lpGbl->hDD;
273 ddgbl.hDD = This->lpLcl->lpGbl->hDD;
274
275 DX_STUB_str("DD_OK");
276 return DD_OK;
277 }
278
279 HRESULT WINAPI
280 StartDirectDrawHel(LPDIRECTDRAW* iface, BOOL reenable)
281 {
282 LPDDRAWI_DIRECTDRAW_INT This = (LPDDRAWI_DIRECTDRAW_INT)iface;
283
284 This->lpLcl->lpGbl->lpDDCBtmp->HELDD.CanCreateSurface = HelDdCanCreateSurface;
285 This->lpLcl->lpGbl->lpDDCBtmp->HELDD.CreateSurface = HelDdCreateSurface;
286 This->lpLcl->lpGbl->lpDDCBtmp->HELDD.CreatePalette = HelDdCreatePalette;
287 This->lpLcl->lpGbl->lpDDCBtmp->HELDD.DestroyDriver = HelDdDestroyDriver;
288 This->lpLcl->lpGbl->lpDDCBtmp->HELDD.FlipToGDISurface = HelDdFlipToGDISurface;
289 This->lpLcl->lpGbl->lpDDCBtmp->HELDD.GetScanLine = HelDdGetScanLine;
290 This->lpLcl->lpGbl->lpDDCBtmp->HELDD.SetColorKey = HelDdSetColorKey;
291 This->lpLcl->lpGbl->lpDDCBtmp->HELDD.SetExclusiveMode = HelDdSetExclusiveMode;
292 This->lpLcl->lpGbl->lpDDCBtmp->HELDD.SetMode = HelDdSetMode;
293 This->lpLcl->lpGbl->lpDDCBtmp->HELDD.WaitForVerticalBlank = HelDdWaitForVerticalBlank;
294
295 This->lpLcl->lpGbl->lpDDCBtmp->HELDD.dwFlags = DDHAL_CB32_CANCREATESURFACE |
296 DDHAL_CB32_CREATESURFACE |
297 DDHAL_CB32_CREATEPALETTE |
298 DDHAL_CB32_DESTROYDRIVER |
299 DDHAL_CB32_FLIPTOGDISURFACE |
300 DDHAL_CB32_GETSCANLINE |
301 DDHAL_CB32_SETCOLORKEY |
302 DDHAL_CB32_SETEXCLUSIVEMODE |
303 DDHAL_CB32_SETMODE |
304 DDHAL_CB32_WAITFORVERTICALBLANK ;
305
306 This->lpLcl->lpGbl->lpDDCBtmp->HELDD.dwSize = sizeof(This->lpLcl->lpDDCB->HELDD);
307
308 This->lpLcl->lpGbl->lpDDCBtmp->HELDDSurface.AddAttachedSurface = HelDdSurfAddAttachedSurface;
309 This->lpLcl->lpGbl->lpDDCBtmp->HELDDSurface.Blt = HelDdSurfBlt;
310 This->lpLcl->lpGbl->lpDDCBtmp->HELDDSurface.DestroySurface = HelDdSurfDestroySurface;
311 This->lpLcl->lpGbl->lpDDCBtmp->HELDDSurface.Flip = HelDdSurfFlip;
312 This->lpLcl->lpGbl->lpDDCBtmp->HELDDSurface.GetBltStatus = HelDdSurfGetBltStatus;
313 This->lpLcl->lpGbl->lpDDCBtmp->HELDDSurface.GetFlipStatus = HelDdSurfGetFlipStatus;
314 This->lpLcl->lpGbl->lpDDCBtmp->HELDDSurface.Lock = HelDdSurfLock;
315 This->lpLcl->lpGbl->lpDDCBtmp->HELDDSurface.reserved4 = HelDdSurfreserved4;
316 This->lpLcl->lpGbl->lpDDCBtmp->HELDDSurface.SetClipList = HelDdSurfSetClipList;
317 This->lpLcl->lpGbl->lpDDCBtmp->HELDDSurface.SetColorKey = HelDdSurfSetColorKey;
318 This->lpLcl->lpGbl->lpDDCBtmp->HELDDSurface.SetOverlayPosition = HelDdSurfSetOverlayPosition;
319 This->lpLcl->lpGbl->lpDDCBtmp->HELDDSurface.SetPalette = HelDdSurfSetPalette;
320 This->lpLcl->lpGbl->lpDDCBtmp->HELDDSurface.Unlock = HelDdSurfUnlock;
321 This->lpLcl->lpGbl->lpDDCBtmp->HELDDSurface.UpdateOverlay = HelDdSurfUpdateOverlay;
322 This->lpLcl->lpGbl->lpDDCBtmp->HELDDSurface.dwFlags = DDHAL_SURFCB32_ADDATTACHEDSURFACE |
323 DDHAL_SURFCB32_BLT |
324 DDHAL_SURFCB32_DESTROYSURFACE |
325 DDHAL_SURFCB32_FLIP |
326 DDHAL_SURFCB32_GETBLTSTATUS |
327 DDHAL_SURFCB32_GETFLIPSTATUS |
328 DDHAL_SURFCB32_LOCK |
329 DDHAL_SURFCB32_RESERVED4 |
330 DDHAL_SURFCB32_SETCLIPLIST |
331 DDHAL_SURFCB32_SETCOLORKEY |
332 DDHAL_SURFCB32_SETOVERLAYPOSITION |
333 DDHAL_SURFCB32_SETPALETTE |
334 DDHAL_SURFCB32_UNLOCK |
335 DDHAL_SURFCB32_UPDATEOVERLAY;
336
337 This->lpLcl->lpGbl->lpDDCBtmp->HELDDSurface.dwSize = sizeof(This->lpLcl->lpDDCB->HELDDSurface);
338
339 /*
340 This->lpLcl->lpDDCB->HELDDPalette.DestroyPalette = HelDdPalDestroyPalette;
341 This->lpLcl->lpDDCB->HELDDPalette.SetEntries = HelDdPalSetEntries;
342 This->lpLcl->lpDDCB->HELDDPalette.dwSize = sizeof(This->lpLcl->lpDDCB->HELDDPalette);
343 */
344
345 /*
346 This->lpLcl->lpDDCB->HELDDExeBuf.CanCreateExecuteBuffer = HelDdExeCanCreateExecuteBuffer;
347 This->lpLcl->lpDDCB->HELDDExeBuf.CreateExecuteBuffer = HelDdExeCreateExecuteBuffer;
348 This->lpLcl->lpDDCB->HELDDExeBuf.DestroyExecuteBuffer = HelDdExeDestroyExecuteBuffer;
349 This->lpLcl->lpDDCB->HELDDExeBuf.LockExecuteBuffer = HelDdExeLockExecuteBuffer;
350 This->lpLcl->lpDDCB->HELDDExeBuf.UnlockExecuteBuffer = HelDdExeUnlockExecuteBuffer;
351 */
352
353 return DD_OK;
354 }
355
356
357 HRESULT WINAPI
358 StartDirectDrawHal(LPDIRECTDRAW* iface, BOOL reenable)
359 {
360
361
362 LPDWORD mpFourCC;
363 DDHALINFO mHALInfo;
364 BOOL newmode = FALSE;
365 LPDDSURFACEDESC mpTextures;
366 D3DHAL_CALLBACKS mD3dCallbacks;
367 D3DHAL_GLOBALDRIVERDATA mD3dDriverData;
368 DDHAL_DDEXEBUFCALLBACKS mD3dBufferCallbacks;
369 LPDDRAWI_DIRECTDRAW_INT This = (LPDDRAWI_DIRECTDRAW_INT)iface;
370
371 RtlZeroMemory(&mHALInfo, sizeof(DDHALINFO));
372 RtlZeroMemory(&mD3dCallbacks, sizeof(D3DHAL_CALLBACKS));
373 RtlZeroMemory(&mD3dDriverData, sizeof(D3DHAL_GLOBALDRIVERDATA));
374 RtlZeroMemory(&mD3dBufferCallbacks, sizeof(DDHAL_DDEXEBUFCALLBACKS));
375
376
377 if (reenable == FALSE)
378 {
379 ddgbl.lpDDCBtmp = DxHeapMemAlloc(sizeof(DDHAL_CALLBACKS));
380 if ( ddgbl.lpDDCBtmp == NULL)
381 {
382 return DD_FALSE;
383 }
384 }
385 else
386 {
387 RtlZeroMemory(ddgbl.lpDDCBtmp,sizeof(DDHAL_CALLBACKS));
388 }
389
390 /*
391 * Startup DX HAL step one of three
392 */
393 if (!DdCreateDirectDrawObject(This->lpLcl->lpGbl, (HDC)This->lpLcl->hDC))
394 {
395 DxHeapMemFree(ddgbl.lpDDCBtmp);
396 return DD_FALSE;
397 }
398
399
400
401 /* Some card disable the dx after it have been created so
402 * we are force reanble it
403 */
404 if (!DdReenableDirectDrawObject(This->lpLcl->lpGbl, &newmode))
405 {
406 DxHeapMemFree(ddgbl.lpDDCBtmp);
407 return DD_FALSE;
408 }
409
410 if (!DdQueryDirectDrawObject(This->lpLcl->lpGbl,
411 &mHALInfo,
412 &ddgbl.lpDDCBtmp->HALDD,
413 &ddgbl.lpDDCBtmp->HALDDSurface,
414 &ddgbl.lpDDCBtmp->HALDDPalette,
415 &mD3dCallbacks,
416 &mD3dDriverData,
417 &mD3dBufferCallbacks,
418 NULL,
419 NULL,
420 NULL))
421 {
422 DxHeapMemFree(This->lpLcl->lpGbl->lpModeInfo);
423 DxHeapMemFree(ddgbl.lpDDCBtmp);
424 // FIXME Close DX fristcall and second call
425 return DD_FALSE;
426 }
427
428 /* Alloc mpFourCC */
429 mpFourCC = NULL;
430 if (mHALInfo.ddCaps.dwNumFourCCCodes)
431 {
432 mpFourCC = (DWORD *) DxHeapMemAlloc(sizeof(DWORD) * mHALInfo.ddCaps.dwNumFourCCCodes);
433 if (mpFourCC == NULL)
434 {
435 DxHeapMemFree(ddgbl.lpDDCBtmp);
436 // FIXME Close DX fristcall and second call
437 return DD_FALSE;
438 }
439 }
440
441 /* Alloc mpTextures */
442 mpTextures = NULL;
443
444 if (mD3dDriverData.dwNumTextureFormats)
445 {
446 mpTextures = (DDSURFACEDESC*) DxHeapMemAlloc(sizeof(DDSURFACEDESC) * mD3dDriverData.dwNumTextureFormats);
447 if (mpTextures == NULL)
448 {
449 DxHeapMemFree( mpFourCC);
450 DxHeapMemFree(ddgbl.lpDDCBtmp);
451 // FIXME Close DX fristcall and second call
452 }
453 return DD_FALSE;
454 }
455
456
457 /* Get all basic data from the driver */
458 if (!DdQueryDirectDrawObject(
459 This->lpLcl->lpGbl,
460 &mHALInfo,
461 &ddgbl.lpDDCBtmp->HALDD,
462 &ddgbl.lpDDCBtmp->HALDDSurface,
463 &ddgbl.lpDDCBtmp->HALDDPalette,
464 &mD3dCallbacks,
465 &mD3dDriverData,
466 &ddgbl.lpDDCBtmp->HALDDExeBuf,
467 (DDSURFACEDESC*)mpTextures,
468 mpFourCC,
469 NULL))
470 {
471 DxHeapMemFree( mpFourCC);
472 DxHeapMemFree( mpTextures);
473 DxHeapMemFree(ddgbl.lpDDCBtmp);
474 // FIXME Close DX fristcall and second call
475 return DD_FALSE;
476 }
477
478 memcpy(&ddgbl.vmiData, &mHALInfo.vmiData,sizeof(VIDMEMINFO));
479 memcpy(&ddgbl.ddCaps, &mHALInfo.ddCaps,sizeof(DDCORECAPS));
480
481 This->lpLcl->lpGbl->dwNumFourCC = mHALInfo.ddCaps.dwNumFourCCCodes;
482 This->lpLcl->lpGbl->lpdwFourCC = mpFourCC;
483
484 This->lpLcl->lpGbl->dwMonitorFrequency = mHALInfo.dwMonitorFrequency;
485 This->lpLcl->lpGbl->dwModeIndex = mHALInfo.dwModeIndex;
486 This->lpLcl->lpGbl->dwNumModes = mHALInfo.dwNumModes;
487 This->lpLcl->lpGbl->lpModeInfo = mHALInfo.lpModeInfo;
488 This->lpLcl->lpGbl->hInstance = mHALInfo.hInstance;
489 This->lpLcl->lpGbl->lp16DD = This->lpLcl->lpGbl;
490
491 /* FIXME convert mpTextures to DDHALMODEINFO */
492 DxHeapMemFree( mpTextures);
493
494 /* FIXME D3D setup mD3dCallbacks and mD3dDriverData */
495 return DD_OK;
496 }