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