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