Release 980517
[wine/hacks.git] / multimedia / mixer.c
blob4b554e69610790128340ec70299c24e91bb90bd3
1 /*
2 * Sample MIXER Wine Driver for Linux
4 * Copyright 1997 Marcus Meissner
5 */
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <unistd.h>
10 #include <fcntl.h>
11 #include <sys/ioctl.h>
12 #include "windows.h"
13 #include "user.h"
14 #include "driver.h"
15 #include "mmsystem.h"
16 #include "debug.h"
18 #ifdef HAVE_SYS_SOUNDCARD_H
19 # include <sys/soundcard.h>
20 #endif
21 #ifdef HAVE_MACHINE_SOUNDCARD_H
22 # include <machine/soundcard.h>
23 #endif
25 #define MIXER_DEV "/dev/mixer"
27 #ifdef SOUND_VERSION
28 #define IOCTL(a,b,c) ioctl(a,b,&c)
29 #else
30 #define IOCTL(a,b,c) (c = ioctl(a,b,c) )
31 #endif
34 /**************************************************************************
35 * MIX_GetDevCaps [internal]
37 static DWORD MIX_GetDevCaps(WORD wDevID, LPMIXERCAPS16 lpCaps, DWORD dwSize)
39 #ifdef HAVE_OSS
40 int mixer,mask;
42 TRACE(mmaux,"(%04X, %p, %lu);\n", wDevID, lpCaps, dwSize);
43 if (lpCaps == NULL) return MMSYSERR_NOTENABLED;
44 if ((mixer = open(MIXER_DEV, O_RDWR)) < 0) {
45 WARN(mmaux, "mixer device not available !\n");
46 return MMSYSERR_NOTENABLED;
48 lpCaps->wMid = 0xAA;
49 lpCaps->wPid = 0x55;
50 lpCaps->vDriverVersion = 0x0100;
51 strcpy(lpCaps->szPname,"WINE Generic Mixer");
52 if (ioctl(mixer, SOUND_MIXER_READ_DEVMASK, &mask) == -1) {
53 close(mixer);
54 perror("ioctl mixer SOUND_MIXER_DEVMASK");
55 return MMSYSERR_NOTENABLED;
57 /* FIXME: can the Linux Mixer differ between multiple mixertargets? */
58 lpCaps->cDestinations = 1;
59 lpCaps->fdwSupport = 0; /* No bits defined yet */
61 close(mixer);
62 return MMSYSERR_NOERROR;
63 #else
64 return MMSYSERR_NOTENABLED;
65 #endif
68 #ifdef HAVE_OSS
69 static char *sdlabels[SOUND_MIXER_NRDEVICES] = SOUND_DEVICE_LABELS;
70 static char *sdnames[SOUND_MIXER_NRDEVICES] = SOUND_DEVICE_NAMES;
71 #endif
73 /**************************************************************************
74 * MIX_GetLineInfo [internal]
76 static DWORD MIX_GetLineInfo(WORD wDevID, LPMIXERLINE16 lpml, DWORD fdwInfo)
78 #ifdef HAVE_OSS
79 int mixer,i,j,devmask,recsrc,recmask;
81 TRACE(mmaux,"(%04X, %p, %lu);\n", wDevID, lpml, fdwInfo);
82 if (lpml == NULL) return MMSYSERR_NOTENABLED;
83 if ((mixer = open(MIXER_DEV, O_RDWR)) < 0)
84 return MMSYSERR_NOTENABLED;
86 if (ioctl(mixer, SOUND_MIXER_READ_DEVMASK, &devmask) == -1) {
87 close(mixer);
88 perror("ioctl mixer SOUND_MIXER_DEVMASK");
89 return MMSYSERR_NOTENABLED;
91 if (ioctl(mixer, SOUND_MIXER_READ_RECSRC, &recsrc) == -1) {
92 close(mixer);
93 perror("ioctl mixer SOUND_MIXER_RECSRC");
94 return MMSYSERR_NOTENABLED;
96 if (ioctl(mixer, SOUND_MIXER_READ_RECMASK, &recmask) == -1) {
97 close(mixer);
98 perror("ioctl mixer SOUND_MIXER_RECMASK");
99 return MMSYSERR_NOTENABLED;
101 lpml->cbStruct = sizeof(MIXERLINE16);
102 /* FIXME: set all the variables correctly... the lines below
103 * are very wrong...
105 lpml->fdwLine = MIXERLINE_LINEF_ACTIVE;
106 lpml->cChannels = 2;
108 switch (fdwInfo & MIXER_GETLINEINFOF_QUERYMASK) {
109 case MIXER_GETLINEINFOF_DESTINATION:
110 /* FIXME: Linux doesn't seem to support multiple outputs?
111 * So we have only one outputtype, Speaker.
113 lpml->dwComponentType = MIXERLINE_COMPONENTTYPE_DST_SPEAKERS;
114 /* we have all connections found in the devmask */
115 lpml->cConnections = 0;
116 for (j=0;j<31;j++)
117 if (devmask & (1<<j))
118 lpml->cConnections++;
119 break;
120 case MIXER_GETLINEINFOF_SOURCE:
121 for (i=j=0;j<31;j++) {
122 if (devmask & (1<<j)) {
123 if (lpml->dwSource == i)
124 break;
125 i++;
128 strcpy(lpml->szShortName,sdlabels[i]);
129 strcpy(lpml->szName,sdnames[i]);
130 lpml->dwLineID = i;
131 switch (i) {
132 case SOUND_MIXER_SYNTH:
133 lpml->dwComponentType = MIXERLINE_COMPONENTTYPE_SRC_SYNTHESIZER;
134 lpml->fdwLine |= MIXERLINE_LINEF_SOURCE;
135 break;
136 case SOUND_MIXER_CD:
137 lpml->dwComponentType = MIXERLINE_COMPONENTTYPE_SRC_COMPACTDISC;
138 lpml->fdwLine |= MIXERLINE_LINEF_SOURCE;
139 break;
140 case SOUND_MIXER_LINE:
141 lpml->dwComponentType = MIXERLINE_COMPONENTTYPE_SRC_LINE;
142 lpml->fdwLine |= MIXERLINE_LINEF_SOURCE;
143 break;
144 case SOUND_MIXER_MIC:
145 lpml->dwComponentType = MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE;
146 lpml->fdwLine |= MIXERLINE_LINEF_SOURCE;
147 break;
148 case SOUND_MIXER_PCM:
149 lpml->dwComponentType = MIXERLINE_COMPONENTTYPE_SRC_WAVEOUT;
150 lpml->fdwLine |= MIXERLINE_LINEF_SOURCE;
151 break;
152 default:
153 ERR(mmaux,"Mixertype %d not handle.\n",i);
154 break;
156 break;
157 case MIXER_GETLINEINFOF_LINEID:
158 FIXME(mmaux,"_LINEID (%ld) not implemented yet.\n",lpml->dwLineID);
159 break;
160 case MIXER_GETLINEINFOF_COMPONENTTYPE:
161 FIXME(mmaux," _COMPONENTTYPE not implemented yet.\n");
162 break;
163 case MIXER_GETLINEINFOF_TARGETTYPE:
164 FIXME(mmaux,"_TARGETTYPE not implemented yet.\n");
165 break;
167 lpml->Target.dwType = MIXERLINE_TARGETTYPE_AUX;
168 close(mixer);
169 return MMSYSERR_NOERROR;
170 #else
171 return MMSYSERR_NOTENABLED;
172 #endif
175 /**************************************************************************
176 * MIX_GetLineInfo [internal]
178 static DWORD MIX_Open(WORD wDevID, LPMIXEROPENDESC lpmod, DWORD flags)
180 #ifdef HAVE_OSS
182 TRACE(mmaux,"(%04X, %p, %lu);\n",wDevID,lpmod,flags);
183 if (lpmod == NULL) return MMSYSERR_NOTENABLED;
184 /* hmm. We don't keep the mixer device open. So just pretend it works */
185 return MMSYSERR_NOERROR;
186 #else
187 return MMSYSERR_NOTENABLED;
188 #endif
191 /**************************************************************************
192 * mixMessage [sample driver]
194 DWORD mixMessage(WORD wDevID, WORD wMsg, DWORD dwUser,
195 DWORD dwParam1, DWORD dwParam2)
197 TRACE(mmaux,"(%04X, %04X, %08lX, %08lX, %08lX);\n",
198 wDevID, wMsg, dwUser, dwParam1, dwParam2);
199 switch(wMsg) {
200 case MXDM_GETDEVCAPS:
201 return MIX_GetDevCaps(wDevID,(LPMIXERCAPS16)dwParam1,dwParam2);
202 case MXDM_GETLINEINFO:
203 return MIX_GetLineInfo(wDevID,(LPMIXERLINE16)dwParam1,dwParam2);
204 case MXDM_GETNUMDEVS:
205 TRACE(mmsys,"return 1;\n");
206 return 1;
207 case MXDM_OPEN:
208 return MIX_Open(wDevID,(LPMIXEROPENDESC)dwParam1,dwParam2);
209 default:
210 WARN(mmaux,"unknown message %d!\n",wMsg);
212 return MMSYSERR_NOTSUPPORTED;