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

Last change on this file since 8568 was 8568, checked in by sandervl, 23 years ago

Updates for wave playback

File size: 9.3 KB
Line 
1/* $Id: initwinmm.cpp,v 1.9 2002-06-04 17:36:55 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
69BOOL fMMPMAvailable = FALSE;
70
71DWORD (APIENTRY *pfnmciSendCommand)(WORD wDeviceID,
72 WORD wMessage,
73 DWORD dwParam1,
74 PVOID dwParam2,
75 WORD wUserParm) = NULL;
76DWORD (APIENTRY *pfnmciGetErrorString)(DWORD dwError,
77 LPSTR lpstrBuffer,
78 WORD wLength) = NULL;
79
80//******************************************************************************
81//******************************************************************************
82void WIN32API DisableWaveAudio()
83{
84 fMMPMAvailable = FALSE;
85 pfnmciGetErrorString = NULL;
86 pfnmciSendCommand = NULL;
87}
88//******************************************************************************
89//******************************************************************************
90BOOL WINAPI LibMainWinmm(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID fImpLoad)
91{
92 static BOOL bInitDone = FALSE;
93 char szError[CCHMAXPATH];
94 HKEY hKey;
95
96 switch (fdwReason)
97 {
98 case DLL_PROCESS_ATTACH:
99 {
100 if (!MULTIMEDIA_CreateIData(hinstDLL))
101 return FALSE;
102
103 if (!bInitDone) { /* to be done only once */
104 if (!MULTIMEDIA_MciInit() /*|| !MMDRV_Init() */ ) {
105 MULTIMEDIA_DeleteIData();
106 return FALSE;
107 }
108 bInitDone = TRUE;
109 }
110 DWORD dwVolume;
111
112 dwVolume = PROFILE_GetOdinIniInt(WINMM_SECTION, DEFVOL_KEY, 100);
113 dwVolume = (dwVolume*0xFFFF)/100;
114 dwVolume = (dwVolume << 16) | dwVolume;
115 WaveOut::setDefaultVolume(dwVolume);
116
117 // try to load the MDM library, not MMPM directly!!!
118 if (DosLoadModule(szError, sizeof(szError),
119 "MDM.DLL", &MMPMLibraryHandle) != NO_ERROR)
120 {
121 // this system has no MMPM :-(
122 fMMPMAvailable = FALSE;
123 }
124 else
125 {
126 /* detect if MMPM is available */
127 if (DosQueryProcAddr(MMPMLibraryHandle,
128 1, /* ORD_MCISENDCOMMAND */
129 NULL,
130 (PFN*)&pfnmciSendCommand) != NO_ERROR)
131 {
132 fMMPMAvailable = FALSE;
133 }
134 else
135 {
136 fMMPMAvailable = TRUE;
137 }
138
139 /* see if we can get the address for the mciGetErrorString function */
140 if (fMMPMAvailable == TRUE)
141 {
142 if (DosQueryProcAddr(MMPMLibraryHandle,
143 3, /* ORD_MCIGETERRORSTRING */
144 NULL,
145 (PFN*)&pfnmciGetErrorString) != NO_ERROR)
146 pfnmciGetErrorString = NULL;
147 }
148 dprintf(("MMPM/2 is available; hmod %x", MMPMLibraryHandle));
149 dprintf(("mciSendCommand %x", pfnmciSendCommand));
150 dprintf(("mciGetErrorString %x", pfnmciGetErrorString));
151 }
152 if(fMMPMAvailable && RegOpenKeyA(HKEY_LOCAL_MACHINE, CUSTOM_BUILD_OPTIONS_KEY, &hKey) == 0)
153 {
154 DWORD dwSize, dwType;
155 DWORD dwFlag;
156
157 dwSize = sizeof(dwFlag);
158 LONG rc = RegQueryValueExA(hKey, DISABLE_AUDIO_KEY,
159 NULL, &dwType,
160 (LPBYTE)&dwFlag,
161 &dwSize);
162
163 if(rc == 0 && dwType == REG_DWORD) {
164 if(dwFlag) {
165 fMMPMAvailable = FALSE;
166 pfnmciGetErrorString = NULL;
167 pfnmciSendCommand = NULL;
168 }
169 }
170 RegCloseKey(hKey);
171 }
172 mixerInit();
173 return TRUE;
174 }
175
176 case DLL_THREAD_ATTACH:
177 case DLL_THREAD_DETACH:
178 return TRUE;
179
180 case DLL_PROCESS_DETACH:
181 MULTIMEDIA_DeleteIData();
182 auxOS2Close(); /* Close aux device if necessary */
183 IRTMidiShutdown; /* Shutdown RT Midi subsystem, if running. */
184
185 mixerExit();
186 if(MMPMLibraryHandle) DosFreeModule(MMPMLibraryHandle);
187 return TRUE;
188 }
189 return FALSE;
190}
191/****************************************************************************/
192/* _DLL_InitTerm is the function that gets called by the operating system */
193/* loader when it loads and frees this DLL for each process that accesses */
194/* this DLL. However, it only gets called the first time the DLL is loaded */
195/* and the last time it is freed for a particular process. The system */
196/* linkage convention MUST be used because the operating system loader is */
197/* calling this function. */
198/****************************************************************************/
199ULONG APIENTRY inittermWinmm(ULONG hModule, ULONG ulFlag)
200{
201 /*-------------------------------------------------------------------------*/
202 /* If ulFlag is zero then the DLL is being loaded so initialization should */
203 /* be performed. If ulFlag is 1 then the DLL is being freed so */
204 /* termination should be performed. */
205 /*-------------------------------------------------------------------------*/
206
207 switch (ulFlag)
208 {
209 case 0 :
210 ParseLogStatusWINMM();
211
212 dllHandle = RegisterLxDll(hModule, LibMainWinmm, (PVOID)&winmm_PEResTab);
213 if(dllHandle == 0)
214 return 0UL;/* Error */
215
216 dprintf(("winmm init %s %s (%x)", __DATE__, __TIME__, inittermWinmm));
217 break;
218 case 1 :
219 auxOS2Close(); /* SvL: Close aux device if necessary */
220 if(dllHandle) {
221 UnregisterLxDll(dllHandle);
222 }
223 break;
224 default :
225 return 0UL;
226 }
227
228 /***********************************************************/
229 /* A non-zero value must be returned to indicate success. */
230 /***********************************************************/
231 return 1UL;
232}
233//******************************************************************************
234//******************************************************************************
235DWORD APIENTRY mymciSendCommand(WORD wDeviceID,
236 WORD wMessage,
237 DWORD dwParam1,
238 PVOID dwParam2,
239 WORD wUserParm)
240{
241 if(pfnmciSendCommand == NULL) {
242 DebugInt3();
243 return MCIERR_CANNOT_LOAD_DRIVER;
244 }
245 USHORT sel = RestoreOS2FS();
246 DWORD ret = pfnmciSendCommand(wDeviceID, wMessage, dwParam1, dwParam2, wUserParm);
247 SetFS(sel);
248 return ret;
249}
250//******************************************************************************
251//******************************************************************************
252DWORD APIENTRY mymciGetErrorString(DWORD dwError,
253 LPSTR lpstrBuffer,
254 WORD wLength)
255{
256 if(pfnmciGetErrorString == NULL) {
257 DebugInt3();
258 return MCIERR_CANNOT_LOAD_DRIVER;
259 }
260 USHORT sel = RestoreOS2FS();
261 DWORD ret = pfnmciGetErrorString(dwError, lpstrBuffer, wLength);
262 SetFS(sel);
263 return ret;
264}
265//******************************************************************************
266//******************************************************************************
Note: See TracBrowser for help on using the repository browser.