Reverse the order for deleting the items in resetcontent to correctly
[wine] / dlls / winmm / wineoss / mmaux.c
1 /*
2  * Sample AUXILARY 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  */
20
21 #include "config.h"
22
23 #include <stdarg.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #ifdef HAVE_UNISTD_H
27 # include <unistd.h>
28 #endif
29 #include <fcntl.h>
30 #ifdef HAVE_SYS_IOCTL_H
31 # include <sys/ioctl.h>
32 #endif
33
34 #include "windef.h"
35 #include "winbase.h"
36 #include "mmddk.h"
37 #include "oss.h"
38 #include "wine/unicode.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, LPAUXCAPSW lpCaps, DWORD dwSize)
69 {
70     int         mixer, volume;
71     static const WCHAR ini[] = {'O','S','S',' ','A','u','x',0};
72
73     TRACE("(%04X, %p, %lu);\n", wDevID, lpCaps, dwSize);
74     if (lpCaps == NULL) return MMSYSERR_NOTENABLED;
75     if ((mixer = open(MIXER_DEV, O_RDWR)) < 0) {
76         WARN("mixer device not available !\n");
77         return MMSYSERR_NOTENABLED;
78     }
79     if (ioctl(mixer, SOUND_MIXER_READ_LINE, &volume) == -1) {
80         close(mixer);
81         WARN("unable to read mixer !\n");
82         return MMSYSERR_NOTENABLED;
83     }
84     close(mixer);
85     lpCaps->wMid = 0xAA;
86     lpCaps->wPid = 0x55;
87     lpCaps->vDriverVersion = 0x0100;
88     strcpyW(lpCaps->szPname, ini);
89     lpCaps->wTechnology = AUXCAPS_CDAUDIO;
90     lpCaps->dwSupport = AUXCAPS_VOLUME | AUXCAPS_LRVOLUME;
91
92     return MMSYSERR_NOERROR;
93 }
94
95
96 /**************************************************************************
97  *                              AUX_GetVolume                   [internal]
98  */
99 static DWORD AUX_GetVolume(WORD wDevID, LPDWORD lpdwVol)
100 {
101     int         mixer, volume, left, right, cmd;
102
103     TRACE("(%04X, %p);\n", wDevID, lpdwVol);
104     if (lpdwVol == NULL) return MMSYSERR_NOTENABLED;
105     if ((mixer = open(MIXER_DEV, O_RDWR)) < 0) {
106         WARN("mixer device not available !\n");
107         return MMSYSERR_NOTENABLED;
108     }
109     switch(wDevID) {
110     case 0:
111         TRACE("SOUND_MIXER_READ_PCM !\n");
112         cmd = SOUND_MIXER_READ_PCM;
113         break;
114     case 1:
115         TRACE("SOUND_MIXER_READ_SYNTH !\n");
116         cmd = SOUND_MIXER_READ_SYNTH;
117         break;
118     case 2:
119         TRACE("SOUND_MIXER_READ_CD !\n");
120         cmd = SOUND_MIXER_READ_CD;
121         break;
122     case 3:
123         TRACE("SOUND_MIXER_READ_LINE !\n");
124         cmd = SOUND_MIXER_READ_LINE;
125         break;
126     case 4:
127         TRACE("SOUND_MIXER_READ_MIC !\n");
128         cmd = SOUND_MIXER_READ_MIC;
129         break;
130     case 5:
131         TRACE("SOUND_MIXER_READ_VOLUME !\n");
132         cmd = SOUND_MIXER_READ_VOLUME;
133         break;
134     default:
135         WARN("invalid device id=%04X !\n", wDevID);
136         return MMSYSERR_NOTENABLED;
137     }
138     if (ioctl(mixer, cmd, &volume) == -1) {
139         WARN("unable to read mixer !\n");
140         return MMSYSERR_NOTENABLED;
141     }
142     close(mixer);
143     left  = LOBYTE(LOWORD(volume));
144     right = HIBYTE(LOWORD(volume));
145     TRACE("left=%d right=%d !\n", left, right);
146     *lpdwVol = MAKELONG((left * 0xFFFFL) / 100, (right * 0xFFFFL) / 100);
147     return MMSYSERR_NOERROR;
148 }
149
150 /**************************************************************************
151  *                              AUX_SetVolume                   [internal]
152  */
153 static DWORD AUX_SetVolume(WORD wDevID, DWORD dwParam)
154 {
155     int         mixer;
156     int         volume, left, right;
157     int         cmd;
158
159     TRACE("(%04X, %08lX);\n", wDevID, dwParam);
160
161     left   = (LOWORD(dwParam) * 100) >> 16;
162     right  = (HIWORD(dwParam) * 100) >> 16;
163     volume = (right << 8) | left;
164
165     if ((mixer = open(MIXER_DEV, O_RDWR)) < 0) {
166         WARN("mixer device not available !\n");
167         return MMSYSERR_NOTENABLED;
168     }
169
170     switch(wDevID) {
171     case 0:
172         TRACE("SOUND_MIXER_WRITE_PCM !\n");
173         cmd = SOUND_MIXER_WRITE_PCM;
174         break;
175     case 1:
176         TRACE("SOUND_MIXER_WRITE_SYNTH !\n");
177         cmd = SOUND_MIXER_WRITE_SYNTH;
178         break;
179     case 2:
180         TRACE("SOUND_MIXER_WRITE_CD !\n");
181         cmd = SOUND_MIXER_WRITE_CD;
182         break;
183     case 3:
184         TRACE("SOUND_MIXER_WRITE_LINE !\n");
185         cmd = SOUND_MIXER_WRITE_LINE;
186         break;
187     case 4:
188         TRACE("SOUND_MIXER_WRITE_MIC !\n");
189         cmd = SOUND_MIXER_WRITE_MIC;
190         break;
191     case 5:
192         TRACE("SOUND_MIXER_WRITE_VOLUME !\n");
193         cmd = SOUND_MIXER_WRITE_VOLUME;
194         break;
195     default:
196         WARN("invalid device id=%04X !\n", wDevID);
197         return MMSYSERR_NOTENABLED;
198     }
199     if (ioctl(mixer, cmd, &volume) == -1) {
200         WARN("unable to set mixer !\n");
201         return MMSYSERR_NOTENABLED;
202     }
203     close(mixer);
204     return MMSYSERR_NOERROR;
205 }
206
207 #endif
208
209 /**************************************************************************
210  *              auxMessage (WINEOSS.2)
211  */
212 DWORD WINAPI OSS_auxMessage(UINT wDevID, UINT wMsg, DWORD dwUser,
213                             DWORD dwParam1, DWORD dwParam2)
214 {
215     TRACE("(%04X, %04X, %08lX, %08lX, %08lX);\n",
216           wDevID, wMsg, dwUser, dwParam1, dwParam2);
217
218 #ifdef HAVE_OSS
219     switch (wMsg) {
220     case DRVM_INIT:
221         AUXDRV_Init();
222         /* fall through */
223     case DRVM_EXIT:
224     case DRVM_ENABLE:
225     case DRVM_DISABLE:
226         /* FIXME: Pretend this is supported */
227         return 0;
228     case AUXDM_GETDEVCAPS:
229         return AUX_GetDevCaps(wDevID, (LPAUXCAPSW)dwParam1, dwParam2);
230     case AUXDM_GETNUMDEVS:
231         TRACE("return %d;\n", NumDev);
232         return NumDev;
233     case AUXDM_GETVOLUME:
234         return AUX_GetVolume(wDevID, (LPDWORD)dwParam1);
235     case AUXDM_SETVOLUME:
236         return AUX_SetVolume(wDevID, dwParam1);
237     default:
238         WARN("unknown message !\n");
239     }
240     return MMSYSERR_NOTSUPPORTED;
241 #else
242     return MMSYSERR_NOTENABLED;
243 #endif
244 }