Update shell xxxAW wrapper prototypes for fixed SHLWAPI functions.
[wine] / dlls / winmm / wineoss / mmaux.c
1 /* -*- tab-width: 8; c-basic-offset: 4 -*- */
2 /*
3  * Sample AUXILARY Wine Driver
4  *
5  * Copyright 1994 Martin Ayotte
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20  */
21
22 #define EMULATE_SB16
23
24 #include "config.h"
25
26 #include <stdlib.h>
27 #include <string.h>
28 #include <unistd.h>
29 #include <fcntl.h>
30 #include <sys/ioctl.h>
31 #include "windef.h"
32 #include "mmddk.h"
33 #include "oss.h"
34 #include "wine/debug.h"
35
36 WINE_DEFAULT_DEBUG_CHANNEL(mmaux);
37     
38 #ifdef HAVE_OSS
39
40 #define MIXER_DEV "/dev/mixer"
41     
42 static int      NumDev = 6;
43
44 /*-----------------------------------------------------------------------*/
45
46 static  int     AUXDRV_Init(void)
47 {
48     int mixer;
49
50     if ((mixer = open(MIXER_DEV, O_RDWR)) < 0) {
51         WARN("mixer device not available !\n");
52         NumDev = 0;
53     } else {
54         close(mixer);
55         NumDev = 6;
56     }
57     return NumDev;
58 }
59
60 /**************************************************************************
61  *                              AUX_GetDevCaps                  [internal]
62  */
63 static DWORD AUX_GetDevCaps(WORD wDevID, LPAUXCAPSA lpCaps, DWORD dwSize)
64 {
65     int         mixer,volume;
66     
67     TRACE("(%04X, %p, %lu);\n", wDevID, lpCaps, dwSize);
68     if (lpCaps == NULL) return MMSYSERR_NOTENABLED;
69     if ((mixer = open(MIXER_DEV, O_RDWR)) < 0) {
70         WARN("mixer device not available !\n");
71         return MMSYSERR_NOTENABLED;
72     }
73     if (ioctl(mixer, SOUND_MIXER_READ_LINE, &volume) == -1) {
74         close(mixer);
75         WARN("unable to read mixer !\n");
76         return MMSYSERR_NOTENABLED;
77     }
78     close(mixer);
79 #ifdef EMULATE_SB16
80     lpCaps->wMid = 0x0002;
81     lpCaps->vDriverVersion = 0x0200;
82     lpCaps->dwSupport = AUXCAPS_VOLUME | AUXCAPS_LRVOLUME;
83     switch (wDevID) {
84     case 0:
85         lpCaps->wPid = 0x0196;
86         strcpy(lpCaps->szPname, "SB16 Aux: Wave");
87         lpCaps->wTechnology = AUXCAPS_AUXIN;
88         break;
89     case 1:
90         lpCaps->wPid = 0x0197;
91         strcpy(lpCaps->szPname, "SB16 Aux: Midi Synth");
92         lpCaps->wTechnology = AUXCAPS_AUXIN;
93         break;
94     case 2:
95         lpCaps->wPid = 0x0191;
96         strcpy(lpCaps->szPname, "SB16 Aux: CD");
97         lpCaps->wTechnology = AUXCAPS_CDAUDIO;
98         break;
99     case 3:
100         lpCaps->wPid = 0x0192;
101         strcpy(lpCaps->szPname, "SB16 Aux: Line-In");
102         lpCaps->wTechnology = AUXCAPS_AUXIN;
103         break;
104     case 4:
105         lpCaps->wPid = 0x0193;
106         strcpy(lpCaps->szPname, "SB16 Aux: Mic");
107         lpCaps->wTechnology = AUXCAPS_AUXIN;
108         break;
109     case 5:
110         lpCaps->wPid = 0x0194;
111         strcpy(lpCaps->szPname, "SB16 Aux: Master");
112         lpCaps->wTechnology = AUXCAPS_AUXIN;
113         break;
114     }
115 #else
116     lpCaps->wMid = 0xAA;
117     lpCaps->wPid = 0x55;
118     lpCaps->vDriverVersion = 0x0100;
119     strcpy(lpCaps->szPname, "Generic Linux Auxiliary Driver");
120     lpCaps->wTechnology = AUXCAPS_CDAUDIO;
121     lpCaps->dwSupport = AUXCAPS_VOLUME | AUXCAPS_LRVOLUME;
122 #endif
123     return MMSYSERR_NOERROR;
124 }
125
126
127 /**************************************************************************
128  *                              AUX_GetVolume                   [internal]
129  */
130 static DWORD AUX_GetVolume(WORD wDevID, LPDWORD lpdwVol)
131 {
132     int         mixer, volume, left, right, cmd;
133     
134     TRACE("(%04X, %p);\n", wDevID, lpdwVol);
135     if (lpdwVol == NULL) return MMSYSERR_NOTENABLED;
136     if ((mixer = open(MIXER_DEV, O_RDWR)) < 0) {
137         WARN("mixer device not available !\n");
138         return MMSYSERR_NOTENABLED;
139     }
140     switch(wDevID) {
141     case 0:
142         TRACE("SOUND_MIXER_READ_PCM !\n");
143         cmd = SOUND_MIXER_READ_PCM;
144         break;
145     case 1:
146         TRACE("SOUND_MIXER_READ_SYNTH !\n");
147         cmd = SOUND_MIXER_READ_SYNTH;
148         break;
149     case 2:
150         TRACE("SOUND_MIXER_READ_CD !\n");
151         cmd = SOUND_MIXER_READ_CD;
152         break;
153     case 3:
154         TRACE("SOUND_MIXER_READ_LINE !\n");
155         cmd = SOUND_MIXER_READ_LINE;
156         break;
157     case 4:
158         TRACE("SOUND_MIXER_READ_MIC !\n");
159         cmd = SOUND_MIXER_READ_MIC;
160         break;
161     case 5:
162         TRACE("SOUND_MIXER_READ_VOLUME !\n");
163         cmd = SOUND_MIXER_READ_VOLUME;
164         break;
165     default:
166         WARN("invalid device id=%04X !\n", wDevID);
167         return MMSYSERR_NOTENABLED;
168     }
169     if (ioctl(mixer, cmd, &volume) == -1) {
170         WARN("unable to read mixer !\n");
171         return MMSYSERR_NOTENABLED;
172     }
173     close(mixer);
174     left  = LOBYTE(LOWORD(volume));
175     right = HIBYTE(LOWORD(volume));
176     TRACE("left=%d right=%d !\n", left, right);
177     *lpdwVol = MAKELONG((left * 0xFFFFL) / 100, (right * 0xFFFFL) / 100);
178     return MMSYSERR_NOERROR;
179 }
180
181 /**************************************************************************
182  *                              AUX_SetVolume                   [internal]
183  */
184 static DWORD AUX_SetVolume(WORD wDevID, DWORD dwParam)
185 {
186     int         mixer;
187     int         volume, left, right;
188     int         cmd;
189     
190     TRACE("(%04X, %08lX);\n", wDevID, dwParam);
191     
192     left   = (LOWORD(dwParam) * 100) >> 16;
193     right  = (HIWORD(dwParam) * 100) >> 16;
194     volume = (right << 8) | left;
195     
196     if ((mixer = open(MIXER_DEV, O_RDWR)) < 0) {
197         WARN("mixer device not available !\n");
198         return MMSYSERR_NOTENABLED;
199     }
200     
201     switch(wDevID) {
202     case 0:
203         TRACE("SOUND_MIXER_WRITE_PCM !\n");
204         cmd = SOUND_MIXER_WRITE_PCM;
205         break;
206     case 1:
207         TRACE("SOUND_MIXER_WRITE_SYNTH !\n");
208         cmd = SOUND_MIXER_WRITE_SYNTH;
209         break;
210     case 2:
211         TRACE("SOUND_MIXER_WRITE_CD !\n");
212         cmd = SOUND_MIXER_WRITE_CD;
213         break;
214     case 3:
215         TRACE("SOUND_MIXER_WRITE_LINE !\n");
216         cmd = SOUND_MIXER_WRITE_LINE;
217         break;
218     case 4:
219         TRACE("SOUND_MIXER_WRITE_MIC !\n");
220         cmd = SOUND_MIXER_WRITE_MIC;
221         break;
222     case 5:
223         TRACE("SOUND_MIXER_WRITE_VOLUME !\n");
224         cmd = SOUND_MIXER_WRITE_VOLUME;
225         break;
226     default:
227         WARN("invalid device id=%04X !\n", wDevID);
228         return MMSYSERR_NOTENABLED;
229     }
230     if (ioctl(mixer, cmd, &volume) == -1) {
231         WARN("unable to set mixer !\n");
232         return MMSYSERR_NOTENABLED;
233     }
234     close(mixer);
235     return MMSYSERR_NOERROR;
236 }
237
238 #endif
239
240 /**************************************************************************
241  *              auxMessage (WINEOSS.2)
242  */
243 DWORD WINAPI OSS_auxMessage(UINT wDevID, UINT wMsg, DWORD dwUser, 
244                             DWORD dwParam1, DWORD dwParam2)
245 {
246     TRACE("(%04X, %04X, %08lX, %08lX, %08lX);\n", 
247           wDevID, wMsg, dwUser, dwParam1, dwParam2);
248
249 #ifdef HAVE_OSS
250     switch (wMsg) {
251     case DRVM_INIT:
252         AUXDRV_Init();
253         /* fall through */
254     case DRVM_EXIT:
255     case DRVM_ENABLE:
256     case DRVM_DISABLE:
257         /* FIXME: Pretend this is supported */
258         return 0;
259     case AUXDM_GETDEVCAPS:
260         return AUX_GetDevCaps(wDevID, (LPAUXCAPSA)dwParam1,dwParam2);
261     case AUXDM_GETNUMDEVS:
262         TRACE("return %d;\n", NumDev);
263         return NumDev;
264     case AUXDM_GETVOLUME:
265         return AUX_GetVolume(wDevID, (LPDWORD)dwParam1);
266     case AUXDM_SETVOLUME:
267         return AUX_SetVolume(wDevID, dwParam1);
268     default:
269         WARN("unknown message !\n");
270     }
271     return MMSYSERR_NOTSUPPORTED;
272 #else
273     return MMSYSERR_NOTENABLED;
274 #endif
275 }