source: trunk/src/winmm/initwinmm.cpp@ 10571

Last change on this file since 10571 was 10571, checked in by sandervl, 21 years ago

update

File size: 10.3 KB
Line 
1/* $Id: initwinmm.cpp,v 1.14 2004-04-06 12:31:35 sandervl Exp $
2 *
3 * WINMM DLL entry point
4 *
5 * Copyright 1998 Sander van Leeuwen (sandervl@xs4all.nl)
6 * Copyright 1998 Peter Fitzsimmons
7 * Copyright 2000 Chris Wohlgemuth
8 *
9 *
10 * Project Odin Software License can be found in LICENSE.TXT
11 *
12 */
13
14/*-------------------------------------------------------------*/
15/* INITERM.C -- Source for a custom dynamic link library */
16/* initialization and termination (_DLL_InitTerm) */
17/* function. */
18/* */
19/* When called to perform initialization, this sample function */
20/* gets storage for an array of integers, and initializes its */
21/* elements with random integers. At termination time, it */
22/* frees the array. Substitute your own special processing. */
23/*-------------------------------------------------------------*/
24
25
26/* Include files */
27#define INCL_DOSMODULEMGR
28#define INCL_DOSPROCESS
29#define INCL_DOSSEMAPHORES
30#define INCL_DOSERRORS
31#define INCL_OS2MM
32#include <os2wrap.h> //Odin32 OS/2 api wrappers
33#include <os2mewrap.h> //Odin32 OS/2 MMPM/2 api wrappers
34#include <stdlib.h>
35#include <stdio.h>
36#include <string.h>
37#include <builtin.h>
38#include <misc.h> /*PLF Wed 98-03-18 23:19:26*/
39#include <odin.h>
40#include <win32type.h>
41#include <win32api.h>
42#include <winconst.h>
43#include <odinlx.h>
44#include <initdll.h>
45#include "auxiliary.h"
46#include "winmmtype.h"
47#include "waveoutbase.h"
48#include <win\options.h>
49#include "initwinmm.h"
50#include <custombuild.h>
51#include "mixer.h"
52
53#define DBG_LOCALLOG DBG_initterm
54#include "dbglocal.h"
55
56BOOL MULTIMEDIA_MciInit(void);
57BOOL MULTIMEDIA_CreateIData(HINSTANCE hinstDLL);
58void MULTIMEDIA_DeleteIData(void);
59
60extern "C" {
61void IRTMidiShutdown(); // IRTMidi shutdown routine
62
63 //Win32 resource table (produced by wrc)
64 extern DWORD winmm_PEResTab;
65}
66static HMODULE dllHandle = 0;
67static HMODULE MMPMLibraryHandle = 0;
68
69static char *szBuggyAudio[] = {
70"CWAUD",
71"BSAUD",
72"CRYSTAL"
73};
74
75BOOL fMMPMAvailable = TRUE;
76
77DWORD (APIENTRY *pfnmciSendCommand)(WORD wDeviceID,
78 WORD wMessage,
79 DWORD dwParam1,
80 PVOID dwParam2,
81 WORD wUserParm) = NULL;
82DWORD (APIENTRY *pfnmciGetErrorString)(DWORD dwError,
83 LPSTR lpstrBuffer,
84 WORD wLength) = NULL;
85
86//******************************************************************************
87//******************************************************************************
88void WIN32API DisableWaveAudio()
89{
90 fMMPMAvailable = FALSE;
91 pfnmciGetErrorString = NULL;
92 pfnmciSendCommand = NULL;
93}
94//******************************************************************************
95//******************************************************************************
96BOOL WINAPI LibMainWinmm(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID fImpLoad)
97{
98 static BOOL bInitDone = FALSE;
99 char szError[CCHMAXPATH];
100 char szPDDName[128];
101 HKEY hKey;
102
103 switch (fdwReason)
104 {
105 case DLL_PROCESS_ATTACH:
106 {
107 if (!MULTIMEDIA_CreateIData(hinstDLL))
108 return FALSE;
109
110 if (!bInitDone) { /* to be done only once */
111 if (!MULTIMEDIA_MciInit() /*|| !MMDRV_Init() */ ) {
112 MULTIMEDIA_DeleteIData();
113 return FALSE;
114 }
115 bInitDone = TRUE;
116 }
117 DWORD dwVolume;
118
119 dwVolume = PROFILE_GetOdinIniInt(WINMM_SECTION, DEFVOL_KEY, 100);
120 dwVolume = (dwVolume*0xFFFF)/100;
121 dwVolume = (dwVolume << 16) | dwVolume;
122 WaveOut::setDefaultVolume(dwVolume);
123
124 if(fMMPMAvailable == TRUE)
125 {//if audio access wasn't disabled already, check if mmpm2 is installed
126 // try to load the MDM library, not MMPM directly!!!
127 if (DosLoadModule(szError, sizeof(szError),
128 "MDM.DLL", &MMPMLibraryHandle) != NO_ERROR)
129 {
130 // this system has no MMPM :-(
131 fMMPMAvailable = FALSE;
132 }
133 else
134 {
135 /* detect if MMPM is available */
136 if (DosQueryProcAddr(MMPMLibraryHandle,
137 1, /* ORD_MCISENDCOMMAND */
138 NULL,
139 (PFN*)&pfnmciSendCommand) != NO_ERROR)
140 {
141 fMMPMAvailable = FALSE;
142 }
143 else
144 {
145 fMMPMAvailable = TRUE;
146 }
147
148 /* see if we can get the address for the mciGetErrorString function */
149 if (fMMPMAvailable == TRUE)
150 {
151 if (DosQueryProcAddr(MMPMLibraryHandle,
152 3, /* ORD_MCIGETERRORSTRING */
153 NULL,
154 (PFN*)&pfnmciGetErrorString) != NO_ERROR)
155 pfnmciGetErrorString = NULL;
156 }
157 dprintf(("MMPM/2 is available; hmod %x", MMPMLibraryHandle));
158 dprintf(("mciSendCommand %x", pfnmciSendCommand));
159 dprintf(("mciGetErrorString %x", pfnmciGetErrorString));
160 }
161 }
162
163 if(fMMPMAvailable && RegOpenKeyA(HKEY_LOCAL_MACHINE, CUSTOM_BUILD_OPTIONS_KEY, &hKey) == 0)
164 {
165 DWORD dwSize, dwType;
166 DWORD dwFlag;
167
168 dwSize = sizeof(dwFlag);
169 LONG rc = RegQueryValueExA(hKey, DISABLE_AUDIO_KEY,
170 NULL, &dwType,
171 (LPBYTE)&dwFlag,
172 &dwSize);
173
174 if(rc == 0 && dwType == REG_DWORD) {
175 if(dwFlag) {
176 fMMPMAvailable = FALSE;
177 pfnmciGetErrorString = NULL;
178 pfnmciSendCommand = NULL;
179 }
180 }
181 RegCloseKey(hKey);
182 }
183 if(OSLibGetAudioPDDName(szPDDName) == FALSE) {
184 fMMPMAvailable = FALSE;
185 }
186 else
187 {
188 // Test for buggy audio drivers to turn off audio automagically
189 for(int i=0;i<sizeof(szBuggyAudio)/sizeof(szBuggyAudio[0]);i++)
190 {
191 if(!strncmp(szPDDName, szBuggyAudio[i], strlen(szBuggyAudio[i]))) {
192 dprintf(("Detected driver %s -> turning off audio!!", szPDDName));
193 fMMPMAvailable = FALSE;
194 break;
195 }
196 }
197 }
198 mixerInit();
199 return TRUE;
200 }
201
202 case DLL_THREAD_ATTACH:
203 case DLL_THREAD_DETACH:
204 return TRUE;
205
206 case DLL_PROCESS_DETACH:
207 WaveInOut::shutdown();
208 MULTIMEDIA_DeleteIData();
209 auxOS2Close(); /* Close aux device if necessary */
210 IRTMidiShutdown; /* Shutdown RT Midi subsystem, if running. */
211
212 mixerExit();
213 if(MMPMLibraryHandle) DosFreeModule(MMPMLibraryHandle);
214 return TRUE;
215 }
216 return FALSE;
217}
218/****************************************************************************/
219/* _DLL_InitTerm is the function that gets called by the operating system */
220/* loader when it loads and frees this DLL for each process that accesses */
221/* this DLL. However, it only gets called the first time the DLL is loaded */
222/* and the last time it is freed for a particular process. The system */
223/* linkage convention MUST be used because the operating system loader is */
224/* calling this function. */
225/****************************************************************************/
226ULONG APIENTRY inittermWinmm(ULONG hModule, ULONG ulFlag)
227{
228 /*-------------------------------------------------------------------------*/
229 /* If ulFlag is zero then the DLL is being loaded so initialization should */
230 /* be performed. If ulFlag is 1 then the DLL is being freed so */
231 /* termination should be performed. */
232 /*-------------------------------------------------------------------------*/
233
234 switch (ulFlag)
235 {
236 case 0 :
237 ParseLogStatusWINMM();
238
239 dllHandle = RegisterLxDll(hModule, LibMainWinmm, (PVOID)&winmm_PEResTab);
240 if(dllHandle == 0)
241 return 0UL;/* Error */
242
243 dprintf(("winmm init %s %s (%x)", __DATE__, __TIME__, inittermWinmm));
244 break;
245 case 1 :
246 auxOS2Close(); /* SvL: Close aux device if necessary */
247 if(dllHandle) {
248 UnregisterLxDll(dllHandle);
249 }
250 break;
251 default :
252 return 0UL;
253 }
254
255 /***********************************************************/
256 /* A non-zero value must be returned to indicate success. */
257 /***********************************************************/
258 return 1UL;
259}
260//******************************************************************************
261//******************************************************************************
262DWORD APIENTRY mymciSendCommand(WORD wDeviceID,
263 WORD wMessage,
264 DWORD dwParam1,
265 PVOID dwParam2,
266 WORD wUserParm)
267{
268 if(pfnmciSendCommand == NULL) {
269 DebugInt3();
270 return MCIERR_CANNOT_LOAD_DRIVER;
271 }
272 USHORT sel = RestoreOS2FS();
273 DWORD ret = pfnmciSendCommand(wDeviceID, wMessage, dwParam1, dwParam2, wUserParm);
274 SetFS(sel);
275 return ret;
276}
277//******************************************************************************
278//******************************************************************************
279DWORD APIENTRY mymciGetErrorString(DWORD dwError,
280 LPSTR lpstrBuffer,
281 WORD wLength)
282{
283 if(pfnmciGetErrorString == NULL) {
284 DebugInt3();
285 return MCIERR_CANNOT_LOAD_DRIVER;
286 }
287 USHORT sel = RestoreOS2FS();
288 DWORD ret = pfnmciGetErrorString(dwError, lpstrBuffer, wLength);
289 SetFS(sel);
290 return ret;
291}
292//******************************************************************************
293//******************************************************************************
Note: See TracBrowser for help on using the repository browser.