Added include <errno.h>.
[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 #ifdef HAVE_UNISTD_H
29 # include <unistd.h>
30 #endif
31 #include <fcntl.h>
32 #ifdef HAVE_SYS_IOCTL_H
33 # include <sys/ioctl.h>
34 #endif
35
36 #include "windef.h"
37 #include "mmddk.h"
38 #include "oss.h"
39 #include "wine/debug.h"
40
41 WINE_DEFAULT_DEBUG_CHANNEL(mmaux);
42
43 #ifdef HAVE_OSS
44
45 #define MIXER_DEV "/dev/mixer"
46
47 static int      NumDev = 6;
48
49 /*-----------------------------------------------------------------------*/
50
51 static  int     AUXDRV_Init(void)
52 {
53     int mixer;
54
55     if ((mixer = open(MIXER_DEV, O_RDWR)) < 0) {
56         WARN("mixer device not available !\n");
57         NumDev = 0;
58     } else {
59         close(mixer);
60         NumDev = 6;
61     }
62     return NumDev;
63 }
64
65 /**************************************************************************
66  *                              AUX_GetDevCaps                  [internal]
67  */
68 static DWORD AUX_GetDevCaps(WORD wDevID, LPAUXCAPSA lpCaps, DWORD dwSize)
69 {
70     int         mixer,volume;
71
72     TRACE("(%04X, %p, %lu);\n", wDevID, lpCaps, dwSize);
73     if (lpCaps == NULL) return MMSYSERR_NOTENABLED;
74     if ((mixer = open(MIXER_DEV, O_RDWR)) < 0) {
75         WARN("mixer device not available !\n");
76         return MMSYSERR_NOTENABLED;
77     }
78     if (ioctl(mixer, SOUND_MIXER_READ_LINE, &volume) == -1) {
79         close(mixer);
80         WARN("unable to read mixer !\n");
81         return MMSYSERR_NOTENABLED;
82     }
83     close(mixer);
84 #ifdef EMULATE_SB16
85     lpCaps->wMid = 0x0002;
86     lpCaps->vDriverVersion = 0x0200;
87     lpCaps->dwSupport = AUXCAPS_VOLUME | AUXCAPS_LRVOLUME;
88     switch (wDevID) {
89     case 0:
90         lpCaps->wPid = 0x0196;
91         strcpy(lpCaps->szPname, "SB16 Aux: Wave");
92         lpCaps->wTechnology = AUXCAPS_AUXIN;
93         break;
94     case 1:
95         lpCaps->wPid = 0x0197;
96         strcpy(lpCaps->szPname, "SB16 Aux: Midi Synth");
97         lpCaps->wTechnology = AUXCAPS_AUXIN;
98         break;
99     case 2:
100         lpCaps->wPid = 0x0191;
101         strcpy(lpCaps->szPname, "SB16 Aux: CD");
102         lpCaps->wTechnology = AUXCAPS_CDAUDIO;
103         break;
104     case 3:
105         lpCaps->wPid = 0x0192;
106         strcpy(lpCaps->szPname, "SB16 Aux: Line-In");
107         lpCaps->wTechnology = AUXCAPS_AUXIN;
108         break;
109     case 4:
110         lpCaps->wPid = 0x0193;
111         strcpy(lpCaps->szPname, "SB16 Aux: Mic");
112         lpCaps->wTechnology = AUXCAPS_AUXIN;
113         break;
114     case 5:
115         lpCaps->wPid = 0x0194;
116         strcpy(lpCaps->szPname, "SB16 Aux: Master");
117         lpCaps->wTechnology = AUXCAPS_AUXIN;
118         break;
119     }
120 #else
121     lpCaps->wMid = 0xAA;
122     lpCaps->wPid = 0x55;
123     lpCaps->vDriverVersion = 0x0100;
124     strcpy(lpCaps->szPname, "Generic Linux Auxiliary Driver");
125     lpCaps->wTechnology = AUXCAPS_CDAUDIO;
126     lpCaps->dwSupport = AUXCAPS_VOLUME | AUXCAPS_LRVOLUME;
127 #endif
128     return MMSYSERR_NOERROR;
129 }
130
131
132 /**************************************************************************
133  *                              AUX_GetVolume                   [internal]
134  */
135 static DWORD AUX_GetVolume(WORD wDevID, LPDWORD lpdwVol)
136 {
137     int         mixer, volume, left, right, cmd;
138
139     TRACE("(%04X, %p);\n", wDevID, lpdwVol);
140     if (lpdwVol == NULL) return MMSYSERR_NOTENABLED;
141     if ((mixer = open(MIXER_DEV, O_RDWR)) < 0) {
142         WARN("mixer device not available !\n");
143         return MMSYSERR_NOTENABLED;
144     }
145     switch(wDevID) {
146     case 0:
147         TRACE("SOUND_MIXER_READ_PCM !\n");
148         cmd = SOUND_MIXER_READ_PCM;
149         break;
150     case 1:
151         TRACE("SOUND_MIXER_READ_SYNTH !\n");
152         cmd = SOUND_MIXER_READ_SYNTH;
153         break;
154     case 2:
155         TRACE("SOUND_MIXER_READ_CD !\n");
156         cmd = SOUND_MIXER_READ_CD;
157         break;
158     case 3:
159         TRACE("SOUND_MIXER_READ_LINE !\n");
160         cmd = SOUND_MIXER_READ_LINE;
161         break;
162     case 4:
163         TRACE("SOUND_MIXER_READ_MIC !\n");
164         cmd = SOUND_MIXER_READ_MIC;
165         break;
166     case 5:
167         TRACE("SOUND_MIXER_READ_VOLUME !\n");
168         cmd = SOUND_MIXER_READ_VOLUME;
169         break;
170     default:
171         WARN("invalid device id=%04X !\n", wDevID);
172         return MMSYSERR_NOTENABLED;
173     }
174     if (ioctl(mixer, cmd, &volume) == -1) {
175         WARN("unable to read mixer !\n");
176         return MMSYSERR_NOTENABLED;
177     }
178     close(mixer);
179     left  = LOBYTE(LOWORD(volume));
180     right = HIBYTE(LOWORD(volume));
181     TRACE("left=%d right=%d !\n", left, right);
182     *lpdwVol = MAKELONG((left * 0xFFFFL) / 100, (right * 0xFFFFL) / 100);
183     return MMSYSERR_NOERROR;
184 }
185
186 /**************************************************************************
187  *                              AUX_SetVolume                   [internal]
188  */
189 static DWORD AUX_SetVolume(WORD wDevID, DWORD dwParam)
190 {
191     int         mixer;
192     int         volume, left, right;
193     int         cmd;
194
195     TRACE("(%04X, %08lX);\n", wDevID, dwParam);
196
197     left   = (LOWORD(dwParam) * 100) >> 16;
198     right  = (HIWORD(dwParam) * 100) >> 16;
199     volume = (right << 8) | left;
200
201     if ((mixer = open(MIXER_DEV, O_RDWR)) < 0) {
202         WARN("mixer device not available !\n");
203         return MMSYSERR_NOTENABLED;
204     }
205
206     switch(wDevID) {
207     case 0:
208         TRACE("SOUND_MIXER_WRITE_PCM !\n");
209         cmd = SOUND_MIXER_WRITE_PCM;
210         break;
211     case 1:
212         TRACE("SOUND_MIXER_WRITE_SYNTH !\n");
213         cmd = SOUND_MIXER_WRITE_SYNTH;
214         break;
215     case 2:
216         TRACE("SOUND_MIXER_WRITE_CD !\n");
217         cmd = SOUND_MIXER_WRITE_CD;
218         break;
219     case 3:
220         TRACE("SOUND_MIXER_WRITE_LINE !\n");
221         cmd = SOUND_MIXER_WRITE_LINE;
222         break;
223     case 4:
224         TRACE("SOUND_MIXER_WRITE_MIC !\n");
225         cmd = SOUND_MIXER_WRITE_MIC;
226         break;
227     case 5:
228         TRACE("SOUND_MIXER_WRITE_VOLUME !\n");
229         cmd = SOUND_MIXER_WRITE_VOLUME;
230         break;
231     default:
232         WARN("invalid device id=%04X !\n", wDevID);
233         return MMSYSERR_NOTENABLED;
234     }
235     if (ioctl(mixer, cmd, &volume) == -1) {
236         WARN("unable to set mixer !\n");
237         return MMSYSERR_NOTENABLED;
238     }
239     close(mixer);
240     return MMSYSERR_NOERROR;
241 }
242
243 #endif
244
245 /**************************************************************************
246  *              auxMessage (WINEOSS.2)
247  */
248 DWORD WINAPI OSS_auxMessage(UINT wDevID, UINT wMsg, DWORD dwUser,
249                             DWORD dwParam1, DWORD dwParam2)
250 {
251     TRACE("(%04X, %04X, %08lX, %08lX, %08lX);\n",
252           wDevID, wMsg, dwUser, dwParam1, dwParam2);
253
254 #ifdef HAVE_OSS
255     switch (wMsg) {
256     case DRVM_INIT:
257         AUXDRV_Init();
258         /* fall through */
259     case DRVM_EXIT:
260     case DRVM_ENABLE:
261     case DRVM_DISABLE:
262         /* FIXME: Pretend this is supported */
263         return 0;
264     case AUXDM_GETDEVCAPS:
265         return AUX_GetDevCaps(wDevID, (LPAUXCAPSA)dwParam1,dwParam2);
266     case AUXDM_GETNUMDEVS:
267         TRACE("return %d;\n", NumDev);
268         return NumDev;
269     case AUXDM_GETVOLUME:
270         return AUX_GetVolume(wDevID, (LPDWORD)dwParam1);
271     case AUXDM_SETVOLUME:
272         return AUX_SetVolume(wDevID, dwParam1);
273     default:
274         WARN("unknown message !\n");
275     }
276     return MMSYSERR_NOTSUPPORTED;
277 #else
278     return MMSYSERR_NOTENABLED;
279 #endif
280 }