Fixed a few compilation warnings
[wine/multimedia.git] / dlls / ddraw / main.c
blob24b37f7eb43d9323f4c46e6e62e1d5e769d28e23
1 /* DirectDraw Base Functions
3 * Copyright 1997-1999 Marcus Meissner
4 * Copyright 1998 Lionel Ulmer (most of Direct3D stuff)
5 */
7 #include "config.h"
9 #include <unistd.h>
10 #include <assert.h>
11 #include <fcntl.h>
12 #include <string.h>
13 #include <stdlib.h>
14 #include <stdio.h>
16 #include "winerror.h"
17 #include "heap.h"
18 #include "wine/exception.h"
19 #include "debugtools.h"
21 #include "initguid.h"
22 #include "ddraw.h"
23 #include "d3d.h"
25 /* This for all the enumeration and creation of D3D-related objects */
26 #include "ddraw_private.h"
28 #define MAX_DDRAW_DRIVERS 3
29 static ddraw_driver * ddraw_drivers[MAX_DDRAW_DRIVERS];
30 static int nrof_ddraw_drivers = 0;
32 DEFAULT_DEBUG_CHANNEL(ddraw);
34 /* register a direct draw driver. We better not use malloc for we are in
35 * the ELF startup initialisation at this point.
37 void ddraw_register_driver(ddraw_driver *driver) {
38 ddraw_drivers[nrof_ddraw_drivers++] = driver;
40 /* increase MAX_DDRAW_DRIVERS if the line below triggers */
41 assert(nrof_ddraw_drivers <= MAX_DDRAW_DRIVERS);
44 /**********************************************************************/
46 typedef struct {
47 LPVOID lpCallback;
48 LPVOID lpContext;
49 } DirectDrawEnumerateProcData;
51 /***********************************************************************
52 * DirectDrawEnumerateExA (DDRAW.*)
54 HRESULT WINAPI DirectDrawEnumerateExA(
55 LPDDENUMCALLBACKEXA lpCallback, LPVOID lpContext, DWORD dwFlags)
57 int i;
58 GUID zeroGUID;
59 TRACE("(%p,%p, %08lx)\n", lpCallback, lpContext, dwFlags);
61 if (TRACE_ON(ddraw)) {
62 DPRINTF(" Flags : ");
63 if (dwFlags & DDENUM_ATTACHEDSECONDARYDEVICES)
64 DPRINTF("DDENUM_ATTACHEDSECONDARYDEVICES ");
65 if (dwFlags & DDENUM_DETACHEDSECONDARYDEVICES)
66 DPRINTF("DDENUM_DETACHEDSECONDARYDEVICES ");
67 if (dwFlags & DDENUM_NONDISPLAYDEVICES)
68 DPRINTF("DDENUM_NONDISPLAYDEVICES ");
69 DPRINTF("\n");
71 if (dwFlags & DDENUM_ATTACHEDSECONDARYDEVICES) {
72 FIXME("no attached secondary devices supported.\n");
73 /*return E_FAIL;*/
76 memset(&zeroGUID,0,sizeof(zeroGUID));
78 /* we have at least one DDRAW driver */
79 if (ddraw_drivers[0]) {
80 if (!lpCallback(
81 &zeroGUID, /* FIXME: or NULL? -MM */
82 "WINE DirectDraw",
83 "display",
84 lpContext,
85 0 /* FIXME: flags not supported here */
87 return DD_OK;
89 /* Invoke callback for what flags we do support */
90 for (i=0;i<MAX_DDRAW_DRIVERS;i++) {
91 if (!ddraw_drivers[i])
92 continue;
93 if (ddraw_drivers[i]->createDDRAW(NULL)) /* !0 is failing */
94 continue;
95 TRACE("Enumerating %s/%s interface\n",ddraw_drivers[i]->name,ddraw_drivers[i]->type);
96 if (!lpCallback(
97 ddraw_drivers[i]->guid,
98 (LPSTR)ddraw_drivers[i]->name,
99 (LPSTR)ddraw_drivers[i]->type,
100 lpContext,
101 0 /* FIXME: flags not supported here */
103 return DD_OK;
105 if (nrof_ddraw_drivers) {
106 TRACE("Enumerating the default interface\n");
107 if (!lpCallback(NULL,"WINE (default)", "display", lpContext, 0))
108 return DD_OK;
111 /* Unsupported flags */
112 if (dwFlags & DDENUM_NONDISPLAYDEVICES) {
113 FIXME("no non-display devices supported.\n");
115 if (dwFlags & DDENUM_DETACHEDSECONDARYDEVICES) {
116 FIXME("no detached secondary devices supported.\n");
119 return DD_OK;
122 /***********************************************************************
123 * DirectDrawEnumerateExW (DDRAW.*)
126 static BOOL CALLBACK DirectDrawEnumerateExProcW(
127 GUID *lpGUID, LPSTR lpDriverDescription, LPSTR lpDriverName,
128 LPVOID lpContext, HMONITOR hm)
130 DirectDrawEnumerateProcData *pEPD = (DirectDrawEnumerateProcData*)lpContext;
131 LPWSTR lpDriverDescriptionW =
132 HEAP_strdupAtoW(GetProcessHeap(), 0, lpDriverDescription);
133 LPWSTR lpDriverNameW =
134 HEAP_strdupAtoW(GetProcessHeap(), 0, lpDriverName);
136 BOOL bResult = (*(LPDDENUMCALLBACKEXW *) pEPD->lpCallback)(
137 lpGUID, lpDriverDescriptionW, lpDriverNameW, pEPD->lpContext, hm);
139 HeapFree(GetProcessHeap(), 0, lpDriverDescriptionW);
140 HeapFree(GetProcessHeap(), 0, lpDriverNameW);
141 return bResult;
144 /**********************************************************************/
146 HRESULT WINAPI DirectDrawEnumerateExW(
147 LPDDENUMCALLBACKEXW lpCallback, LPVOID lpContext, DWORD dwFlags)
149 DirectDrawEnumerateProcData epd;
150 epd.lpCallback = (LPVOID) lpCallback;
151 epd.lpContext = lpContext;
153 return DirectDrawEnumerateExA(DirectDrawEnumerateExProcW, (LPVOID) &epd, 0);
156 /***********************************************************************
157 * DirectDrawEnumerateA (DDRAW.*)
160 static BOOL CALLBACK DirectDrawEnumerateProcA(
161 GUID *lpGUID, LPSTR lpDriverDescription, LPSTR lpDriverName,
162 LPVOID lpContext, HMONITOR hm)
164 DirectDrawEnumerateProcData *pEPD = (DirectDrawEnumerateProcData*)lpContext;
166 return ((LPDDENUMCALLBACKA) pEPD->lpCallback)(
167 lpGUID, lpDriverDescription, lpDriverName, pEPD->lpContext);
170 /**********************************************************************/
172 HRESULT WINAPI DirectDrawEnumerateA(
173 LPDDENUMCALLBACKA lpCallback, LPVOID lpContext)
175 DirectDrawEnumerateProcData epd;
176 epd.lpCallback = (LPVOID) lpCallback;
177 epd.lpContext = lpContext;
179 return DirectDrawEnumerateExA(DirectDrawEnumerateProcA, (LPVOID) &epd, 0);
182 /***********************************************************************
183 * DirectDrawEnumerateW (DDRAW.*)
186 static BOOL WINAPI DirectDrawEnumerateProcW(
187 GUID *lpGUID, LPWSTR lpDriverDescription, LPWSTR lpDriverName,
188 LPVOID lpContext, HMONITOR hm)
190 DirectDrawEnumerateProcData *pEPD = (DirectDrawEnumerateProcData*)lpContext;
192 return ((LPDDENUMCALLBACKW) pEPD->lpCallback)(
193 lpGUID, lpDriverDescription, lpDriverName, pEPD->lpContext);
196 /**********************************************************************/
198 HRESULT WINAPI DirectDrawEnumerateW(
199 LPDDENUMCALLBACKW lpCallback, LPVOID lpContext)
201 DirectDrawEnumerateProcData epd;
202 epd.lpCallback = (LPVOID) lpCallback;
203 epd.lpContext = lpContext;
205 return DirectDrawEnumerateExW(DirectDrawEnumerateProcW, (LPVOID) &epd, 0);
208 /******************************************************************************
209 * DirectDraw Window Procedure
211 static LRESULT WINAPI DDWndProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)
213 LRESULT ret;
214 IDirectDrawImpl* ddraw = NULL;
215 DWORD lastError;
217 /* FIXME(ddraw,"(0x%04x,%s,0x%08lx,0x%08lx),stub!\n",(int)hwnd,SPY_GetMsgName(msg),(long)wParam,(long)lParam); */
219 SetLastError( ERROR_SUCCESS );
220 ddraw = (IDirectDrawImpl*)GetPropA( hwnd, ddProp );
221 if( (!ddraw) && ( ( lastError = GetLastError() ) != ERROR_SUCCESS ))
222 ERR("Unable to retrieve this ptr from window. Error %08lx\n",lastError);
224 if( ddraw ) {
225 /* Perform any special direct draw functions */
226 if (msg==WM_PAINT)
227 ddraw->d->paintable = 1;
229 /* Now let the application deal with the rest of this */
230 if( ddraw->d->mainWindow ) {
232 /* Don't think that we actually need to call this but...
233 * might as well be on the safe side of things...
236 /* I changed hwnd to ddraw->d->mainWindow as I did not see why
237 * it should be the procedures of our fake window that gets called
238 * instead of those of the window provided by the application.
239 * And with this patch, mouse clicks work with Monkey Island III
240 * - Lionel
242 ret = DefWindowProcA( ddraw->d->mainWindow, msg, wParam, lParam );
244 if( !ret ) {
245 /* We didn't handle the message - give it to the application */
246 if (ddraw && ddraw->d->mainWindow)
248 WNDPROC winproc = (WNDPROC)GetWindowLongA( ddraw->d->mainWindow, GWL_WNDPROC );
249 ret = CallWindowProcA(winproc, ddraw->d->mainWindow, msg, wParam, lParam );
252 return ret;
253 } /* else FALLTHROUGH */
254 } /* else FALLTHROUGH */
255 return DefWindowProcA(hwnd,msg,wParam,lParam);
258 /***********************************************************************
259 * DirectDrawCreate
261 HRESULT WINAPI DirectDrawCreate(
262 LPGUID lpGUID, LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter
264 IDirectDrawImpl** ilplpDD=(IDirectDrawImpl**)lplpDD;
265 WNDCLASSA wc;
266 HRESULT ret = 0;
267 int i,drvindex=0;
268 GUID zeroGUID;
270 struct ddraw_driver *ddd = NULL;
272 if (!HIWORD(lpGUID)) lpGUID = NULL;
274 TRACE("(%s,%p,%p)\n",debugstr_guid(lpGUID),ilplpDD,pUnkOuter);
276 memset(&zeroGUID,0,sizeof(zeroGUID));
277 while (1) {
278 ddd = NULL;
279 if ( ( !lpGUID ) ||
280 ( IsEqualGUID( &zeroGUID, lpGUID ) ) ||
281 ( IsEqualGUID( &IID_IDirectDraw, lpGUID ) ) ||
282 ( IsEqualGUID( &IID_IDirectDraw2, lpGUID ) ) ||
283 ( IsEqualGUID( &IID_IDirectDraw4, lpGUID ) ) ||
284 ( IsEqualGUID( &IID_IDirectDraw7, lpGUID ) )
286 /* choose an interface out of the list */
287 for (i=0;i<nrof_ddraw_drivers;i++) {
288 ddraw_driver *xddd = ddraw_drivers[i];
289 if (!xddd)
290 continue;
291 if (!ddd || (ddd->preference<xddd->preference)) {
292 drvindex = i;
293 ddd = xddd;
296 } else {
297 for (i=0;i<nrof_ddraw_drivers;i++) {
298 if (!ddraw_drivers[i])
299 continue;
300 if (IsEqualGUID(ddraw_drivers[i]->guid,lpGUID)) {
301 drvindex = i;
302 ddd = ddraw_drivers[i];
303 break;
307 if (!ddd) {
308 if (!nrof_ddraw_drivers) {
309 ERR("DirectDrawCreate(%s,%p,%p): no DirectDraw drivers compiled in.\n",debugstr_guid(lpGUID),lplpDD,pUnkOuter);
310 return DDERR_NODIRECTDRAWHW;
312 ERR("DirectDrawCreate(%s,%p,%p): did not recognize requested GUID.\n",debugstr_guid(lpGUID),lplpDD,pUnkOuter);
313 return DDERR_INVALIDDIRECTDRAWGUID;
315 TRACE("using \"%s\" driver, calling %p\n",ddd->name,ddd->createDDRAW);
317 ret = ddd->createDDRAW(lplpDD);
318 if (!ret)
319 break;
320 ddraw_drivers[drvindex] = NULL; /* mark this one as unusable */
322 wc.style = CS_GLOBALCLASS;
323 wc.lpfnWndProc = DDWndProc;
324 wc.cbClsExtra = 0;
325 wc.cbWndExtra = 0;
327 /* We can be a child of the desktop since we're really important */
328 wc.hInstance= 0;
329 wc.hIcon = 0;
330 wc.hCursor = (HCURSOR)IDC_ARROWA;
331 wc.hbrBackground = NULL_BRUSH;
332 wc.lpszMenuName = 0;
333 wc.lpszClassName = "WINE_DirectDraw";
334 (*ilplpDD)->d->winclass = RegisterClassA(&wc);
335 return ret;
338 /***********************************************************************
339 * DirectDrawCreateEx
341 HRESULT WINAPI DirectDrawCreateEx(
342 LPGUID lpGUID, LPVOID* lplpDD, REFIID iid, LPUNKNOWN pUnkOuter
344 LPDIRECTDRAW ddraw;
345 HRESULT hres;
347 FIXME("(%p,%p,%s,%p), might be wrong.\n",lpGUID,lplpDD,debugstr_guid(iid),pUnkOuter);
349 hres=DirectDrawCreate(lpGUID,(LPDIRECTDRAW*)&ddraw,pUnkOuter);
350 if (!hres) {
351 hres=IDirectDraw_QueryInterface(ddraw,iid,lplpDD);
352 IDirectDraw_Release(ddraw);
354 return hres;
357 /*******************************************************************************
358 * DirectDraw ClassFactory
360 * Heavily inspired (well, can you say completely copied :-) ) from DirectSound
363 typedef struct {
364 /* IUnknown fields */
365 ICOM_VFIELD(IClassFactory);
366 DWORD ref;
367 } IClassFactoryImpl;
369 static HRESULT WINAPI
370 DDCF_QueryInterface(LPCLASSFACTORY iface,REFIID riid,LPVOID *ppobj) {
371 ICOM_THIS(IClassFactoryImpl,iface);
373 FIXME("(%p)->(%s,%p),stub!\n",This,debugstr_guid(riid),ppobj);
374 return E_NOINTERFACE;
377 static ULONG WINAPI
378 DDCF_AddRef(LPCLASSFACTORY iface) {
379 ICOM_THIS(IClassFactoryImpl,iface);
380 return ++(This->ref);
383 static ULONG WINAPI DDCF_Release(LPCLASSFACTORY iface) {
384 ICOM_THIS(IClassFactoryImpl,iface);
385 /* static class, won't be freed */
386 return --(This->ref);
389 static HRESULT WINAPI DDCF_CreateInstance(
390 LPCLASSFACTORY iface,LPUNKNOWN pOuter,REFIID riid,LPVOID *ppobj
392 ICOM_THIS(IClassFactoryImpl,iface);
394 TRACE("(%p)->(%p,%s,%p)\n",This,pOuter,debugstr_guid(riid),ppobj);
395 if ( ( IsEqualGUID( &IID_IDirectDraw, riid ) ) ||
396 ( IsEqualGUID( &IID_IDirectDraw2, riid ) ) ||
397 ( IsEqualGUID( &IID_IDirectDraw4, riid ) ) ) {
398 /* FIXME: reuse already created DirectDraw if present? */
399 return DirectDrawCreate((LPGUID) riid,(LPDIRECTDRAW*)ppobj,pOuter);
401 return CLASS_E_CLASSNOTAVAILABLE;
404 static HRESULT WINAPI DDCF_LockServer(LPCLASSFACTORY iface,BOOL dolock) {
405 ICOM_THIS(IClassFactoryImpl,iface);
406 FIXME("(%p)->(%d),stub!\n",This,dolock);
407 return S_OK;
410 static ICOM_VTABLE(IClassFactory) DDCF_Vtbl =
412 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
413 DDCF_QueryInterface,
414 DDCF_AddRef,
415 DDCF_Release,
416 DDCF_CreateInstance,
417 DDCF_LockServer
419 static IClassFactoryImpl DDRAW_CF = {&DDCF_Vtbl, 1 };
421 /*******************************************************************************
422 * DllGetClassObject [DDRAW.13]
423 * Retrieves class object from a DLL object
425 * NOTES
426 * Docs say returns STDAPI
428 * PARAMS
429 * rclsid [I] CLSID for the class object
430 * riid [I] Reference to identifier of interface for class object
431 * ppv [O] Address of variable to receive interface pointer for riid
433 * RETURNS
434 * Success: S_OK
435 * Failure: CLASS_E_CLASSNOTAVAILABLE, E_OUTOFMEMORY, E_INVALIDARG,
436 * E_UNEXPECTED
438 DWORD WINAPI DDRAW_DllGetClassObject(REFCLSID rclsid,REFIID riid,LPVOID *ppv)
440 TRACE("(%p,%p,%p)\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv);
441 if ( IsEqualGUID( &IID_IClassFactory, riid ) ) {
442 *ppv = (LPVOID)&DDRAW_CF;
443 IClassFactory_AddRef((IClassFactory*)*ppv);
444 return S_OK;
446 FIXME("(%p,%p,%p): no interface found.\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv);
447 return CLASS_E_CLASSNOTAVAILABLE;
451 /*******************************************************************************
452 * DllCanUnloadNow [DDRAW.12] Determines whether the DLL is in use.
454 * RETURNS
455 * Success: S_OK
456 * Failure: S_FALSE
458 DWORD WINAPI DDRAW_DllCanUnloadNow(void) {
459 FIXME("(void): stub\n");
460 return S_FALSE;