2 * Copyright 2009 Maarten Lankhorst
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 #include "wine/port.h"
27 #elif defined(HAVE_OPENAL_AL_H)
28 #include <OpenAL/al.h>
29 #include <OpenAL/alc.h>
36 #include "wine/library.h"
43 #include "propkeydef.h"
44 #include "mmdeviceapi.h"
47 #include "audioclient.h"
48 #include "endpointvolume.h"
49 #include "audiopolicy.h"
53 #include "wine/debug.h"
55 WINE_DEFAULT_DEBUG_CHANNEL(mmdevapi
);
61 static CRITICAL_SECTION_DEBUG openal_crst_debug
=
64 { &openal_crst_debug
.ProcessLocksList
,
65 &openal_crst_debug
.ProcessLocksList
},
66 0, 0, { (DWORD_PTR
)(__FILE__
": openal_crst_debug") }
68 CRITICAL_SECTION openal_crst
= { &openal_crst_debug
, -1, 0, 0, 0, 0 };
70 static void *openal_handle
= RTLD_DEFAULT
;
72 #ifdef SONAME_LIBOPENAL
73 LPALCCREATECONTEXT palcCreateContext
= NULL
;
74 LPALCMAKECONTEXTCURRENT palcMakeContextCurrent
= NULL
;
75 LPALCPROCESSCONTEXT palcProcessContext
= NULL
;
76 LPALCSUSPENDCONTEXT palcSuspendContext
= NULL
;
77 LPALCDESTROYCONTEXT palcDestroyContext
= NULL
;
78 LPALCGETCURRENTCONTEXT palcGetCurrentContext
= NULL
;
79 LPALCGETCONTEXTSDEVICE palcGetContextsDevice
= NULL
;
80 LPALCOPENDEVICE palcOpenDevice
= NULL
;
81 LPALCCLOSEDEVICE palcCloseDevice
= NULL
;
82 LPALCGETERROR palcGetError
= NULL
;
83 LPALCISEXTENSIONPRESENT palcIsExtensionPresent
= NULL
;
84 LPALCGETPROCADDRESS palcGetProcAddress
= NULL
;
85 LPALCGETENUMVALUE palcGetEnumValue
= NULL
;
86 LPALCGETSTRING palcGetString
= NULL
;
87 LPALCGETINTEGERV palcGetIntegerv
= NULL
;
88 LPALCCAPTUREOPENDEVICE palcCaptureOpenDevice
= NULL
;
89 LPALCCAPTURECLOSEDEVICE palcCaptureCloseDevice
= NULL
;
90 LPALCCAPTURESTART palcCaptureStart
= NULL
;
91 LPALCCAPTURESTOP palcCaptureStop
= NULL
;
92 LPALCCAPTURESAMPLES palcCaptureSamples
= NULL
;
93 LPALENABLE palEnable
= NULL
;
94 LPALDISABLE palDisable
= NULL
;
95 LPALISENABLED palIsEnabled
= NULL
;
96 LPALGETSTRING palGetString
= NULL
;
97 LPALGETBOOLEANV palGetBooleanv
= NULL
;
98 LPALGETINTEGERV palGetIntegerv
= NULL
;
99 LPALGETFLOATV palGetFloatv
= NULL
;
100 LPALGETDOUBLEV palGetDoublev
= NULL
;
101 LPALGETBOOLEAN palGetBoolean
= NULL
;
102 LPALGETINTEGER palGetInteger
= NULL
;
103 LPALGETFLOAT palGetFloat
= NULL
;
104 LPALGETDOUBLE palGetDouble
= NULL
;
105 LPALGETERROR palGetError
= NULL
;
106 LPALISEXTENSIONPRESENT palIsExtensionPresent
= NULL
;
107 LPALGETPROCADDRESS palGetProcAddress
= NULL
;
108 LPALGETENUMVALUE palGetEnumValue
= NULL
;
109 LPALLISTENERF palListenerf
= NULL
;
110 LPALLISTENER3F palListener3f
= NULL
;
111 LPALLISTENERFV palListenerfv
= NULL
;
112 LPALLISTENERI palListeneri
= NULL
;
113 LPALLISTENER3I palListener3i
= NULL
;
114 LPALLISTENERIV palListeneriv
= NULL
;
115 LPALGETLISTENERF palGetListenerf
= NULL
;
116 LPALGETLISTENER3F palGetListener3f
= NULL
;
117 LPALGETLISTENERFV palGetListenerfv
= NULL
;
118 LPALGETLISTENERI palGetListeneri
= NULL
;
119 LPALGETLISTENER3I palGetListener3i
= NULL
;
120 LPALGETLISTENERIV palGetListeneriv
= NULL
;
121 LPALGENSOURCES palGenSources
= NULL
;
122 LPALDELETESOURCES palDeleteSources
= NULL
;
123 LPALISSOURCE palIsSource
= NULL
;
124 LPALSOURCEF palSourcef
= NULL
;
125 LPALSOURCE3F palSource3f
= NULL
;
126 LPALSOURCEFV palSourcefv
= NULL
;
127 LPALSOURCEI palSourcei
= NULL
;
128 LPALSOURCE3I palSource3i
= NULL
;
129 LPALSOURCEIV palSourceiv
= NULL
;
130 LPALGETSOURCEF palGetSourcef
= NULL
;
131 LPALGETSOURCE3F palGetSource3f
= NULL
;
132 LPALGETSOURCEFV palGetSourcefv
= NULL
;
133 LPALGETSOURCEI palGetSourcei
= NULL
;
134 LPALGETSOURCE3I palGetSource3i
= NULL
;
135 LPALGETSOURCEIV palGetSourceiv
= NULL
;
136 LPALSOURCEPLAYV palSourcePlayv
= NULL
;
137 LPALSOURCESTOPV palSourceStopv
= NULL
;
138 LPALSOURCEREWINDV palSourceRewindv
= NULL
;
139 LPALSOURCEPAUSEV palSourcePausev
= NULL
;
140 LPALSOURCEPLAY palSourcePlay
= NULL
;
141 LPALSOURCESTOP palSourceStop
= NULL
;
142 LPALSOURCEREWIND palSourceRewind
= NULL
;
143 LPALSOURCEPAUSE palSourcePause
= NULL
;
144 LPALSOURCEQUEUEBUFFERS palSourceQueueBuffers
= NULL
;
145 LPALSOURCEUNQUEUEBUFFERS palSourceUnqueueBuffers
= NULL
;
146 LPALGENBUFFERS palGenBuffers
= NULL
;
147 LPALDELETEBUFFERS palDeleteBuffers
= NULL
;
148 LPALISBUFFER palIsBuffer
= NULL
;
149 LPALBUFFERF palBufferf
= NULL
;
150 LPALBUFFER3F palBuffer3f
= NULL
;
151 LPALBUFFERFV palBufferfv
= NULL
;
152 LPALBUFFERI palBufferi
= NULL
;
153 LPALBUFFER3I palBuffer3i
= NULL
;
154 LPALBUFFERIV palBufferiv
= NULL
;
155 LPALGETBUFFERF palGetBufferf
= NULL
;
156 LPALGETBUFFER3F palGetBuffer3f
= NULL
;
157 LPALGETBUFFERFV palGetBufferfv
= NULL
;
158 LPALGETBUFFERI palGetBufferi
= NULL
;
159 LPALGETBUFFER3I palGetBuffer3i
= NULL
;
160 LPALGETBUFFERIV palGetBufferiv
= NULL
;
161 LPALBUFFERDATA palBufferData
= NULL
;
162 LPALDOPPLERFACTOR palDopplerFactor
= NULL
;
163 LPALDOPPLERVELOCITY palDopplerVelocity
= NULL
;
164 LPALDISTANCEMODEL palDistanceModel
= NULL
;
165 LPALSPEEDOFSOUND palSpeedOfSound
= NULL
;
168 typeof(alcGetCurrentContext
) *get_context
;
169 typeof(alcMakeContextCurrent
) *set_context
;
171 static void load_libopenal(void)
175 #ifdef SONAME_LIBOPENAL
177 openal_handle
= wine_dlopen(SONAME_LIBOPENAL
, RTLD_NOW
, error
, sizeof(error
));
180 ERR("Couldn't load " SONAME_LIBOPENAL
": %s\n", error
);
184 #define LOAD_FUNCPTR(f) \
185 if((p##f = wine_dlsym(openal_handle, #f, NULL, 0)) == NULL) { \
186 ERR("Couldn't lookup %s in libopenal\n", #f); \
190 LOAD_FUNCPTR(alcCreateContext
);
191 LOAD_FUNCPTR(alcMakeContextCurrent
);
192 LOAD_FUNCPTR(alcProcessContext
);
193 LOAD_FUNCPTR(alcSuspendContext
);
194 LOAD_FUNCPTR(alcDestroyContext
);
195 LOAD_FUNCPTR(alcGetCurrentContext
);
196 LOAD_FUNCPTR(alcGetContextsDevice
);
197 LOAD_FUNCPTR(alcOpenDevice
);
198 LOAD_FUNCPTR(alcCloseDevice
);
199 LOAD_FUNCPTR(alcGetError
);
200 LOAD_FUNCPTR(alcIsExtensionPresent
);
201 LOAD_FUNCPTR(alcGetProcAddress
);
202 LOAD_FUNCPTR(alcGetEnumValue
);
203 LOAD_FUNCPTR(alcGetString
);
204 LOAD_FUNCPTR(alcGetIntegerv
);
205 LOAD_FUNCPTR(alcCaptureOpenDevice
);
206 LOAD_FUNCPTR(alcCaptureCloseDevice
);
207 LOAD_FUNCPTR(alcCaptureStart
);
208 LOAD_FUNCPTR(alcCaptureStop
);
209 LOAD_FUNCPTR(alcCaptureSamples
);
210 LOAD_FUNCPTR(alEnable
);
211 LOAD_FUNCPTR(alDisable
);
212 LOAD_FUNCPTR(alIsEnabled
);
213 LOAD_FUNCPTR(alGetString
);
214 LOAD_FUNCPTR(alGetBooleanv
);
215 LOAD_FUNCPTR(alGetIntegerv
);
216 LOAD_FUNCPTR(alGetFloatv
);
217 LOAD_FUNCPTR(alGetDoublev
);
218 LOAD_FUNCPTR(alGetBoolean
);
219 LOAD_FUNCPTR(alGetInteger
);
220 LOAD_FUNCPTR(alGetFloat
);
221 LOAD_FUNCPTR(alGetDouble
);
222 LOAD_FUNCPTR(alGetError
);
223 LOAD_FUNCPTR(alIsExtensionPresent
);
224 LOAD_FUNCPTR(alGetProcAddress
);
225 LOAD_FUNCPTR(alGetEnumValue
);
226 LOAD_FUNCPTR(alListenerf
);
227 LOAD_FUNCPTR(alListener3f
);
228 LOAD_FUNCPTR(alListenerfv
);
229 LOAD_FUNCPTR(alListeneri
);
230 LOAD_FUNCPTR(alListener3i
);
231 LOAD_FUNCPTR(alListeneriv
);
232 LOAD_FUNCPTR(alGetListenerf
);
233 LOAD_FUNCPTR(alGetListener3f
);
234 LOAD_FUNCPTR(alGetListenerfv
);
235 LOAD_FUNCPTR(alGetListeneri
);
236 LOAD_FUNCPTR(alGetListener3i
);
237 LOAD_FUNCPTR(alGetListeneriv
);
238 LOAD_FUNCPTR(alGenSources
);
239 LOAD_FUNCPTR(alDeleteSources
);
240 LOAD_FUNCPTR(alIsSource
);
241 LOAD_FUNCPTR(alSourcef
);
242 LOAD_FUNCPTR(alSource3f
);
243 LOAD_FUNCPTR(alSourcefv
);
244 LOAD_FUNCPTR(alSourcei
);
245 LOAD_FUNCPTR(alSource3i
);
246 LOAD_FUNCPTR(alSourceiv
);
247 LOAD_FUNCPTR(alGetSourcef
);
248 LOAD_FUNCPTR(alGetSource3f
);
249 LOAD_FUNCPTR(alGetSourcefv
);
250 LOAD_FUNCPTR(alGetSourcei
);
251 LOAD_FUNCPTR(alGetSource3i
);
252 LOAD_FUNCPTR(alGetSourceiv
);
253 LOAD_FUNCPTR(alSourcePlayv
);
254 LOAD_FUNCPTR(alSourceStopv
);
255 LOAD_FUNCPTR(alSourceRewindv
);
256 LOAD_FUNCPTR(alSourcePausev
);
257 LOAD_FUNCPTR(alSourcePlay
);
258 LOAD_FUNCPTR(alSourceStop
);
259 LOAD_FUNCPTR(alSourceRewind
);
260 LOAD_FUNCPTR(alSourcePause
);
261 LOAD_FUNCPTR(alSourceQueueBuffers
);
262 LOAD_FUNCPTR(alSourceUnqueueBuffers
);
263 LOAD_FUNCPTR(alGenBuffers
);
264 LOAD_FUNCPTR(alDeleteBuffers
);
265 LOAD_FUNCPTR(alIsBuffer
);
266 LOAD_FUNCPTR(alBufferf
);
267 LOAD_FUNCPTR(alBuffer3f
);
268 LOAD_FUNCPTR(alBufferfv
);
269 LOAD_FUNCPTR(alBufferi
);
270 LOAD_FUNCPTR(alBuffer3i
);
271 LOAD_FUNCPTR(alBufferiv
);
272 LOAD_FUNCPTR(alGetBufferf
);
273 LOAD_FUNCPTR(alGetBuffer3f
);
274 LOAD_FUNCPTR(alGetBufferfv
);
275 LOAD_FUNCPTR(alGetBufferi
);
276 LOAD_FUNCPTR(alGetBuffer3i
);
277 LOAD_FUNCPTR(alGetBufferiv
);
278 LOAD_FUNCPTR(alBufferData
);
279 LOAD_FUNCPTR(alDopplerFactor
);
280 LOAD_FUNCPTR(alDopplerVelocity
);
281 LOAD_FUNCPTR(alDistanceModel
);
282 LOAD_FUNCPTR(alSpeedOfSound
);
288 WARN("Unloading openal\n");
289 if (openal_handle
!= RTLD_DEFAULT
)
290 wine_dlclose(openal_handle
, NULL
, 0);
291 openal_handle
= NULL
;
297 local_contexts
= palcIsExtensionPresent(NULL
, "ALC_EXT_thread_local_context");
300 set_context
= palcGetProcAddress(NULL
, "alcSetThreadContext");
301 get_context
= palcGetProcAddress(NULL
, "alcGetThreadContext");
302 if (!set_context
|| !get_context
)
304 ERR("TLS advertised but functions not found, disabling thread local context\n");
310 set_context
= palcMakeContextCurrent
;
311 get_context
= palcGetCurrentContext
;
316 #endif /*HAVE_OPENAL*/
318 static HINSTANCE instance
;
320 BOOL WINAPI
DllMain(HINSTANCE hinstDLL
, DWORD fdwReason
, LPVOID lpvReserved
)
322 TRACE("(0x%p, %d, %p)\n", hinstDLL
, fdwReason
, lpvReserved
);
326 case DLL_PROCESS_ATTACH
:
328 DisableThreadLibraryCalls(hinstDLL
);
331 #endif /*HAVE_OPENAL*/
333 case DLL_PROCESS_DETACH
:
341 HRESULT WINAPI
DllCanUnloadNow(void)
346 typedef HRESULT (*FnCreateInstance
)(REFIID riid
, LPVOID
*ppobj
);
349 IClassFactory IClassFactory_iface
;
351 FnCreateInstance pfnCreateInstance
;
354 static inline IClassFactoryImpl
*impl_from_IClassFactory(IClassFactory
*iface
)
356 return CONTAINING_RECORD(iface
, IClassFactoryImpl
, IClassFactory_iface
);
359 static HRESULT WINAPI
360 MMCF_QueryInterface(LPCLASSFACTORY iface
, REFIID riid
, LPVOID
*ppobj
)
362 IClassFactoryImpl
*This
= impl_from_IClassFactory(iface
);
363 TRACE("(%p, %s, %p)\n", This
, debugstr_guid(riid
), ppobj
);
366 if (IsEqualIID(riid
, &IID_IUnknown
) ||
367 IsEqualIID(riid
, &IID_IClassFactory
))
370 IUnknown_AddRef(iface
);
374 return E_NOINTERFACE
;
377 static ULONG WINAPI
MMCF_AddRef(LPCLASSFACTORY iface
)
382 static ULONG WINAPI
MMCF_Release(LPCLASSFACTORY iface
)
384 /* static class, won't be freed */
388 static HRESULT WINAPI
MMCF_CreateInstance(
389 LPCLASSFACTORY iface
,
394 IClassFactoryImpl
*This
= impl_from_IClassFactory(iface
);
395 TRACE("(%p, %p, %s, %p)\n", This
, pOuter
, debugstr_guid(riid
), ppobj
);
398 return CLASS_E_NOAGGREGATION
;
401 WARN("invalid parameter\n");
405 return This
->pfnCreateInstance(riid
, ppobj
);
408 static HRESULT WINAPI
MMCF_LockServer(LPCLASSFACTORY iface
, BOOL dolock
)
410 IClassFactoryImpl
*This
= impl_from_IClassFactory(iface
);
411 FIXME("(%p, %d) stub!\n", This
, dolock
);
415 static const IClassFactoryVtbl MMCF_Vtbl
= {
423 static IClassFactoryImpl MMDEVAPI_CF
[] = {
424 { { &MMCF_Vtbl
}, &CLSID_MMDeviceEnumerator
, (FnCreateInstance
)MMDevEnum_Create
}
427 HRESULT WINAPI
DllGetClassObject(REFCLSID rclsid
, REFIID riid
, LPVOID
*ppv
)
430 TRACE("(%s, %s, %p)\n", debugstr_guid(rclsid
), debugstr_guid(riid
), ppv
);
433 WARN("invalid parameter\n");
439 if (!IsEqualIID(riid
, &IID_IClassFactory
) &&
440 !IsEqualIID(riid
, &IID_IUnknown
)) {
441 WARN("no interface for %s\n", debugstr_guid(riid
));
442 return E_NOINTERFACE
;
445 for (i
= 0; i
< sizeof(MMDEVAPI_CF
)/sizeof(MMDEVAPI_CF
[0]); ++i
)
447 if (IsEqualGUID(rclsid
, MMDEVAPI_CF
[i
].rclsid
)) {
448 IUnknown_AddRef(&MMDEVAPI_CF
[i
].IClassFactory_iface
);
449 *ppv
= &MMDEVAPI_CF
[i
];
455 WARN("(%s, %s, %p): no class found.\n", debugstr_guid(rclsid
),
456 debugstr_guid(riid
), ppv
);
457 return CLASS_E_CLASSNOTAVAILABLE
;
460 /***********************************************************************
461 * DllRegisterServer (MMDEVAPI.@)
463 HRESULT WINAPI
DllRegisterServer(void)
465 return __wine_register_resources( instance
, NULL
);
468 /***********************************************************************
469 * DllUnregisterServer (MMDEVAPI.@)
471 HRESULT WINAPI
DllUnregisterServer(void)
473 return __wine_unregister_resources( instance
, NULL
);