Release 1.5.29.
[wine] / dlls / ddrawex / main.c
1 /*        DirectDrawEx
2  *
3  * Copyright 2006 Ulrich Czekalla
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
18  */
19
20
21 #include "wine/debug.h"
22
23 #define COBJMACROS
24
25 #include "winbase.h"
26 #include "wingdi.h"
27 #include "objbase.h"
28 #include "rpcproxy.h"
29
30 #include "ddraw.h"
31
32 #include "initguid.h"
33 #include "ddrawex_private.h"
34
35 WINE_DEFAULT_DEBUG_CHANNEL(ddrawex);
36
37 static HINSTANCE instance;
38
39 /******************************************************************************
40  * DirectDraw ClassFactory implementation
41  ******************************************************************************/
42 typedef struct
43 {
44     IClassFactory IClassFactory_iface;
45     LONG ref;
46     HRESULT (*pfnCreateInstance)(IUnknown *pUnkOuter, REFIID iid, LPVOID *ppObj);
47 } IClassFactoryImpl;
48
49 static inline IClassFactoryImpl *impl_from_IClassFactory(IClassFactory *iface)
50 {
51     return CONTAINING_RECORD(iface, IClassFactoryImpl, IClassFactory_iface);
52 }
53
54 /*******************************************************************************
55  * IDirectDrawClassFactory::QueryInterface
56  *
57  *******************************************************************************/
58 static HRESULT WINAPI IDirectDrawClassFactoryImpl_QueryInterface(IClassFactory *iface, REFIID riid,
59         void **obj)
60 {
61     TRACE("(%p)->(%s,%p)\n", iface, debugstr_guid(riid), obj);
62
63     if (IsEqualGUID(riid, &IID_IUnknown)
64         || IsEqualGUID(riid, &IID_IClassFactory))
65     {
66         IClassFactory_AddRef(iface);
67         *obj = iface;
68         return S_OK;
69     }
70
71     WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
72
73     *obj = NULL;
74     return E_NOINTERFACE;
75 }
76
77 /*******************************************************************************
78  * IDirectDrawClassFactory::AddRef
79  *
80  *******************************************************************************/
81 static ULONG WINAPI IDirectDrawClassFactoryImpl_AddRef(IClassFactory *iface)
82 {
83     IClassFactoryImpl *This = impl_from_IClassFactory(iface);
84     ULONG ref = InterlockedIncrement(&This->ref);
85
86     TRACE("(%p)->() incrementing from %d.\n", This, ref - 1);
87
88     return ref;
89 }
90
91 /*******************************************************************************
92  * IDirectDrawClassFactory::Release
93  *
94  *******************************************************************************/
95 static ULONG WINAPI IDirectDrawClassFactoryImpl_Release(IClassFactory *iface)
96 {
97     IClassFactoryImpl *This = impl_from_IClassFactory(iface);
98     ULONG ref = InterlockedDecrement(&This->ref);
99
100     TRACE("(%p)->() decrementing from %d.\n", This, ref+1);
101
102     if (ref == 0)
103         HeapFree(GetProcessHeap(), 0, This);
104
105     return ref;
106 }
107
108
109 /*******************************************************************************
110  * IDirectDrawClassFactory::CreateInstance
111  *
112  *******************************************************************************/
113 static HRESULT WINAPI IDirectDrawClassFactoryImpl_CreateInstance(IClassFactory *iface,
114         IUnknown *UnkOuter, REFIID riid, void **obj)
115 {
116     IClassFactoryImpl *This = impl_from_IClassFactory(iface);
117
118     TRACE("(%p)->(%p,%s,%p)\n",This,UnkOuter,debugstr_guid(riid),obj);
119
120     return This->pfnCreateInstance(UnkOuter, riid, obj);
121 }
122
123 /*******************************************************************************
124  * IDirectDrawClassFactory::LockServer
125  *
126  *******************************************************************************/
127 static HRESULT WINAPI IDirectDrawClassFactoryImpl_LockServer(IClassFactory *iface,BOOL dolock)
128 {
129     IClassFactoryImpl *This = impl_from_IClassFactory(iface);
130
131     FIXME("(%p)->(%d),stub!\n",This,dolock);
132
133     return S_OK;
134 }
135
136
137 /*******************************************************************************
138  * The class factory VTable
139  *******************************************************************************/
140 static const IClassFactoryVtbl IClassFactory_Vtbl =
141 {
142     IDirectDrawClassFactoryImpl_QueryInterface,
143     IDirectDrawClassFactoryImpl_AddRef,
144     IDirectDrawClassFactoryImpl_Release,
145     IDirectDrawClassFactoryImpl_CreateInstance,
146     IDirectDrawClassFactoryImpl_LockServer
147 };
148
149
150 /******************************************************************************
151  * DirectDrawFactory implementation
152  ******************************************************************************/
153 typedef struct
154 {
155     IDirectDrawFactory IDirectDrawFactory_iface;
156     LONG ref;
157 } IDirectDrawFactoryImpl;
158
159 static inline IDirectDrawFactoryImpl *impl_from_IDirectDrawFactory(IDirectDrawFactory *iface)
160 {
161     return CONTAINING_RECORD(iface, IDirectDrawFactoryImpl, IDirectDrawFactory_iface);
162 }
163
164 /*******************************************************************************
165  * IDirectDrawFactory::QueryInterface
166  *
167  *******************************************************************************/
168 static HRESULT WINAPI IDirectDrawFactoryImpl_QueryInterface(IDirectDrawFactory *iface, REFIID riid,
169         void **obj)
170 {
171     TRACE("(%p)->(%s,%p)\n", iface, debugstr_guid(riid), obj);
172
173     if (IsEqualGUID(riid, &IID_IUnknown)
174         || IsEqualGUID(riid, &IID_IDirectDrawFactory))
175     {
176         IDirectDrawFactory_AddRef(iface);
177         *obj = iface;
178         return S_OK;
179     }
180
181     WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
182
183     *obj = NULL;
184     return E_NOINTERFACE;
185 }
186
187 /*******************************************************************************
188  * IDirectDrawFactory::AddRef
189  *
190  *******************************************************************************/
191 static ULONG WINAPI IDirectDrawFactoryImpl_AddRef(IDirectDrawFactory *iface)
192 {
193     IDirectDrawFactoryImpl *This = impl_from_IDirectDrawFactory(iface);
194     ULONG ref = InterlockedIncrement(&This->ref);
195
196     TRACE("(%p)->() incrementing from %d.\n", This, ref - 1);
197
198     return ref;
199 }
200
201 /*******************************************************************************
202  * IDirectDrawFactory::Release
203  *
204  *******************************************************************************/
205 static ULONG WINAPI IDirectDrawFactoryImpl_Release(IDirectDrawFactory *iface)
206 {
207     IDirectDrawFactoryImpl *This = impl_from_IDirectDrawFactory(iface);
208     ULONG ref = InterlockedDecrement(&This->ref);
209
210     TRACE("(%p)->() decrementing from %d.\n", This, ref+1);
211
212     if (ref == 0)
213         HeapFree(GetProcessHeap(), 0, This);
214
215     return ref;
216 }
217
218 /*******************************************************************************
219  * IDirectDrawFactoryImpl_DirectDrawEnumerate
220  *******************************************************************************/
221 static HRESULT WINAPI
222 IDirectDrawFactoryImpl_DirectDrawEnumerate(IDirectDrawFactory* iface,
223                                            LPDDENUMCALLBACKW lpCallback,
224                                            LPVOID lpContext)
225 {
226     FIXME("Stub!\n");
227     return E_FAIL;
228 }
229
230
231 /*******************************************************************************
232  * Direct Draw Factory VTable
233  *******************************************************************************/
234 static const IDirectDrawFactoryVtbl IDirectDrawFactory_Vtbl =
235 {
236     IDirectDrawFactoryImpl_QueryInterface,
237     IDirectDrawFactoryImpl_AddRef,
238     IDirectDrawFactoryImpl_Release,
239     IDirectDrawFactoryImpl_CreateDirectDraw,
240     IDirectDrawFactoryImpl_DirectDrawEnumerate,
241 };
242
243 /***********************************************************************
244  * CreateDirectDrawFactory
245  *
246  ***********************************************************************/
247 static HRESULT
248 CreateDirectDrawFactory(IUnknown* UnkOuter, REFIID iid, void **obj)
249 {
250     HRESULT hr;
251     IDirectDrawFactoryImpl *This = NULL;
252
253     TRACE("(%p,%s,%p)\n", UnkOuter, debugstr_guid(iid), obj);
254
255     if (UnkOuter != NULL)
256         return CLASS_E_NOAGGREGATION;
257
258     This = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirectDrawFactoryImpl));
259
260     if(!This)
261     {
262         ERR("Out of memory when creating DirectDraw\n");
263         return E_OUTOFMEMORY;
264     }
265
266     This->IDirectDrawFactory_iface.lpVtbl = &IDirectDrawFactory_Vtbl;
267
268     hr = IDirectDrawFactory_QueryInterface(&This->IDirectDrawFactory_iface, iid,  obj);
269
270     if (FAILED(hr))
271         HeapFree(GetProcessHeap(), 0, This);
272
273     return hr;
274 }
275
276
277 /*******************************************************************************
278  * DllCanUnloadNow [DDRAWEX.@]  Determines whether the DLL is in use.
279  */
280 HRESULT WINAPI DllCanUnloadNow(void)
281 {
282     return S_FALSE;
283 }
284
285
286 /*******************************************************************************
287  * DllGetClassObject [DDRAWEX.@]
288  */
289 HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
290 {
291     IClassFactoryImpl *factory;
292
293     TRACE("ddrawex (%s,%s,%p)\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv);
294
295     if (!IsEqualGUID( &IID_IClassFactory, riid)
296         && !IsEqualGUID( &IID_IUnknown, riid))
297         return E_NOINTERFACE;
298
299     if (!IsEqualGUID(&CLSID_DirectDrawFactory, rclsid))
300     {
301         FIXME("%s: no class found.\n", debugstr_guid(rclsid));
302         return CLASS_E_CLASSNOTAVAILABLE;
303     }
304
305     factory = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*factory));
306     if (factory == NULL) return E_OUTOFMEMORY;
307
308     factory->IClassFactory_iface.lpVtbl = &IClassFactory_Vtbl;
309     factory->ref = 1;
310
311     factory->pfnCreateInstance = CreateDirectDrawFactory;
312
313     *ppv = factory;
314
315     return S_OK;
316 }
317
318
319 /***********************************************************************
320  * DllMain
321  */
322 BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD reason, LPVOID lpv)
323 {
324     switch (reason)
325     {
326     case DLL_PROCESS_ATTACH:
327         instance = hInstDLL;
328         DisableThreadLibraryCalls( hInstDLL );
329         break;
330     }
331     return TRUE;
332 }
333
334 /***********************************************************************
335  *              DllRegisterServer (DDRAWEX.@)
336  */
337 HRESULT WINAPI DllRegisterServer(void)
338 {
339     return __wine_register_resources( instance );
340 }
341
342 /***********************************************************************
343  *              DllUnregisterServer (DDRAWEX.@)
344  */
345 HRESULT WINAPI DllUnregisterServer(void)
346 {
347     return __wine_unregister_resources( instance );
348 }