Added support for MCI AVI driver
[wine/testsucceed.git] / multimedia / mixer.c
blob72bded31f4e3aa211f2d2413e8b4c3b8107021a3
1 /*
2 * Sample MIXER Wine Driver for Linux
4 * Copyright 1997 Marcus Meissner
5 */
7 #include <stdlib.h>
8 #include <unistd.h>
9 #include <fcntl.h>
10 #include <sys/ioctl.h>
11 #include "windows.h"
12 #include "user.h"
13 #include "driver.h"
14 #include "multimedia.h"
15 #include "debug.h"
17 #define MIXER_DEV "/dev/mixer"
19 /**************************************************************************
20 * MIX_GetDevCaps [internal]
22 static DWORD MIX_GetDevCaps(WORD wDevID, LPMIXERCAPS16 lpCaps, DWORD dwSize)
24 #ifdef HAVE_OSS
25 int mixer,mask;
27 TRACE(mmaux, "(%04X, %p, %lu);\n", wDevID, lpCaps, dwSize);
28 if (lpCaps == NULL) return MMSYSERR_INVALPARAM;
29 if ((mixer = open(MIXER_DEV, O_RDWR)) < 0) {
30 WARN(mmaux, "mixer device not available !\n");
31 return MMSYSERR_NOTENABLED;
33 lpCaps->wMid = 0xAA;
34 lpCaps->wPid = 0x55;
35 lpCaps->vDriverVersion = 0x0100;
36 strcpy(lpCaps->szPname, "WINE Generic Mixer");
37 if (ioctl(mixer, SOUND_MIXER_READ_DEVMASK, &mask) == -1) {
38 close(mixer);
39 perror("ioctl mixer SOUND_MIXER_DEVMASK");
40 return MMSYSERR_NOTENABLED;
42 /* FIXME: can the Linux Mixer differ between multiple mixertargets? */
43 lpCaps->cDestinations = 1;
44 lpCaps->fdwSupport = 0; /* No bits defined yet */
46 close(mixer);
47 return MMSYSERR_NOERROR;
48 #else
49 return MMSYSERR_NOTENABLED;
50 #endif
53 #ifdef HAVE_OSS
54 static char *sdlabels[SOUND_MIXER_NRDEVICES] = SOUND_DEVICE_LABELS;
55 static char *sdnames[SOUND_MIXER_NRDEVICES] = SOUND_DEVICE_NAMES;
57 static void MIX_GetLineInfoFromIndex(LPMIXERLINE16 lpml, int devmask, DWORD idx)
59 strcpy(lpml->szShortName, sdlabels[idx]);
60 strcpy(lpml->szName, sdnames[idx]);
61 lpml->dwLineID = idx;
62 lpml->dwDestination = 0; /* index for speakers */
63 lpml->cConnections = 1;
64 lpml->cControls = 1;
65 switch (idx) {
66 case SOUND_MIXER_SYNTH:
67 lpml->dwComponentType = MIXERLINE_COMPONENTTYPE_SRC_SYNTHESIZER;
68 lpml->fdwLine |= MIXERLINE_LINEF_SOURCE;
69 break;
70 case SOUND_MIXER_CD:
71 lpml->dwComponentType = MIXERLINE_COMPONENTTYPE_SRC_COMPACTDISC;
72 lpml->fdwLine |= MIXERLINE_LINEF_SOURCE;
73 break;
74 case SOUND_MIXER_LINE:
75 lpml->dwComponentType = MIXERLINE_COMPONENTTYPE_SRC_LINE;
76 lpml->fdwLine |= MIXERLINE_LINEF_SOURCE;
77 break;
78 case SOUND_MIXER_MIC:
79 lpml->dwComponentType = MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE;
80 lpml->fdwLine |= MIXERLINE_LINEF_SOURCE;
81 break;
82 case SOUND_MIXER_PCM:
83 lpml->dwComponentType = MIXERLINE_COMPONENTTYPE_SRC_WAVEOUT;
84 lpml->fdwLine |= MIXERLINE_LINEF_SOURCE;
85 break;
86 default:
87 ERR(mmaux, "Index %ld not handled.\n", idx);
88 break;
91 #endif
93 /**************************************************************************
94 * MIX_GetLineInfo [internal]
96 static DWORD MIX_GetLineInfo(WORD wDevID, LPMIXERLINE16 lpml, DWORD fdwInfo)
98 #ifdef HAVE_OSS
99 int mixer, i, j, devmask, recsrc, recmask;
100 DWORD ret = MMSYSERR_NOERROR;
102 TRACE(mmaux, "(%04X, %p, %lu);\n", wDevID, lpml, fdwInfo);
103 if (lpml == NULL || lpml->cbStruct != sizeof(*lpml))
104 return MMSYSERR_INVALPARAM;
105 if ((mixer = open(MIXER_DEV, O_RDWR)) < 0)
106 return MMSYSERR_NOTENABLED;
108 if (ioctl(mixer, SOUND_MIXER_READ_DEVMASK, &devmask) == -1) {
109 close(mixer);
110 perror("ioctl mixer SOUND_MIXER_DEVMASK");
111 return MMSYSERR_NOTENABLED;
113 if (ioctl(mixer, SOUND_MIXER_READ_RECSRC, &recsrc) == -1) {
114 close(mixer);
115 perror("ioctl mixer SOUND_MIXER_RECSRC");
116 return MMSYSERR_NOTENABLED;
118 if (ioctl(mixer, SOUND_MIXER_READ_RECMASK, &recmask) == -1) {
119 close(mixer);
120 perror("ioctl mixer SOUND_MIXER_RECMASK");
121 return MMSYSERR_NOTENABLED;
124 /* FIXME: set all the variables correctly... the lines below
125 * are very wrong...
127 lpml->fdwLine = MIXERLINE_LINEF_ACTIVE;
128 lpml->cChannels = 2;
130 switch (fdwInfo & MIXER_GETLINEINFOF_QUERYMASK) {
131 case MIXER_GETLINEINFOF_DESTINATION:
132 /* FIXME: Linux doesn't seem to support multiple outputs?
133 * So we have only one outputtype, Speaker.
135 lpml->dwComponentType = MIXERLINE_COMPONENTTYPE_DST_SPEAKERS;
136 /* we have all connections found in the devmask */
137 lpml->cConnections = 0;
138 for (j=0;j<31;j++)
139 if (devmask & (1<<j))
140 lpml->cConnections++;
141 break;
142 case MIXER_GETLINEINFOF_SOURCE:
143 for (i = j = 0; j < 31; j++) {
144 if (devmask & (1 << j)) {
145 if (lpml->dwSource == i)
146 break;
147 i++;
150 MIX_GetLineInfoFromIndex(lpml, devmask, i);
151 break;
152 case MIXER_GETLINEINFOF_LINEID:
153 MIX_GetLineInfoFromIndex(lpml, devmask, lpml->dwLineID);
154 break;
155 case MIXER_GETLINEINFOF_COMPONENTTYPE:
156 TRACE(mmaux, "Getting component type (%08lx)\n", lpml->dwComponentType);
157 switch (lpml->dwComponentType) {
158 case MIXERLINE_COMPONENTTYPE_DST_SPEAKERS:
159 i = -1;
160 break;
161 case MIXERLINE_COMPONENTTYPE_SRC_SYNTHESIZER:
162 i = SOUND_MIXER_SYNTH;
163 break;
164 case MIXERLINE_COMPONENTTYPE_SRC_COMPACTDISC:
165 i = SOUND_MIXER_CD;
166 break;
167 case MIXERLINE_COMPONENTTYPE_SRC_LINE:
168 i = SOUND_MIXER_LINE;
169 break;
170 case MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE:
171 i = SOUND_MIXER_MIC;
172 break;
173 case MIXERLINE_COMPONENTTYPE_SRC_WAVEOUT:
174 i = SOUND_MIXER_PCM;
175 break;
176 default:
177 FIXME(mmaux, "Unhandled component type (%08lx)\n", lpml->dwComponentType);
178 return MMSYSERR_INVALPARAM;
180 if (i != -1 && (devmask & (1 << i))) {
181 strcpy(lpml->szShortName, sdlabels[i]);
182 strcpy(lpml->szName, sdnames[i]);
183 lpml->dwLineID = i;
184 lpml->fdwLine = MIXERLINE_LINEF_SOURCE;
185 } else {
186 lpml->cConnections = 0;
187 for (j=0;j<31;j++)
188 if (devmask & (1<<j))
189 lpml->cConnections++;
190 lpml->dwLineID = 32;
192 break;
193 case MIXER_GETLINEINFOF_TARGETTYPE:
194 FIXME(mmaux, "_TARGETTYPE not implemented yet.\n");
195 break;
197 lpml->Target.dwType = MIXERLINE_TARGETTYPE_AUX;
198 close(mixer);
199 return ret;
200 #else
201 return MMSYSERR_NOTENABLED;
202 #endif
205 /**************************************************************************
206 * MIX_GetLineInfo [internal]
208 static DWORD MIX_Open(WORD wDevID, LPMIXEROPENDESC lpmod, DWORD flags)
210 #ifdef HAVE_OSS
212 TRACE(mmaux, "(%04X, %p, %lu);\n", wDevID,lpmod,flags);
213 if (lpmod == NULL) return MMSYSERR_INVALPARAM;
214 /* hmm. We don't keep the mixer device open. So just pretend it works */
215 return MMSYSERR_NOERROR;
216 #else
217 return MMSYSERR_NOTENABLED;
218 #endif
221 /**************************************************************************
222 * mixMessage [sample driver]
224 DWORD WINAPI mixMessage(WORD wDevID, WORD wMsg, DWORD dwUser,
225 DWORD dwParam1, DWORD dwParam2)
227 TRACE(mmaux, "(%04X, %04X, %08lX, %08lX, %08lX);\n",
228 wDevID, wMsg, dwUser, dwParam1, dwParam2);
230 switch(wMsg) {
231 case MXDM_GETDEVCAPS:
232 return MIX_GetDevCaps(wDevID, (LPMIXERCAPS16)dwParam1, dwParam2);
233 case MXDM_GETLINEINFO:
234 return MIX_GetLineInfo(wDevID, (LPMIXERLINE16)dwParam1, dwParam2);
235 case MXDM_GETNUMDEVS:
236 TRACE(mmaux, "return 1;\n");
237 return 1;
238 case MXDM_OPEN:
239 return MIX_Open(wDevID, (LPMIXEROPENDESC)dwParam1, dwParam2);
240 case MXDM_CLOSE:
241 return MMSYSERR_NOERROR;
242 default:
243 WARN(mmaux, "unknown message %d!\n", wMsg);
245 return MMSYSERR_NOTSUPPORTED;