2 * Sample MIXER Wine Driver for Linux
4 * Copyright 1997 Marcus Meissner
10 #include <sys/ioctl.h>
17 #ifdef HAVE_SYS_SOUNDCARD_H
18 # include <sys/soundcard.h>
20 #ifdef HAVE_MACHINE_SOUNDCARD_H
21 # include <machine/soundcard.h>
24 #define MIXER_DEV "/dev/mixer"
27 #define IOCTL(a,b,c) ioctl(a,b,&c)
29 #define IOCTL(a,b,c) (c = ioctl(a,b,c) )
33 /**************************************************************************
34 * MIX_GetDevCaps [internal]
36 static DWORD MIX_GetDevCaps(WORD wDevID, LPMIXERCAPS16 lpCaps, DWORD dwSize)
41 TRACE(mmaux,"(%04X, %p, %lu);\n", wDevID, lpCaps, dwSize);
42 if (lpCaps == NULL) return MMSYSERR_NOTENABLED;
43 if ((mixer = open(MIXER_DEV, O_RDWR)) < 0) {
44 WARN(mmaux, "mixer device not available !\n");
45 return MMSYSERR_NOTENABLED;
49 lpCaps->vDriverVersion = 0x0100;
50 strcpy(lpCaps->szPname,"WINE Generic Mixer");
51 if (ioctl(mixer, SOUND_MIXER_READ_DEVMASK, &mask) == -1) {
53 perror("ioctl mixer SOUND_MIXER_DEVMASK");
54 return MMSYSERR_NOTENABLED;
56 /* FIXME: can the Linux Mixer differ between multiple mixertargets? */
57 lpCaps->cDestinations = 1;
58 lpCaps->fdwSupport = 0; /* No bits defined yet */
61 return MMSYSERR_NOERROR;
63 return MMSYSERR_NOTENABLED;
68 static char *sdlabels[SOUND_MIXER_NRDEVICES] = SOUND_DEVICE_LABELS;
69 static char *sdnames[SOUND_MIXER_NRDEVICES] = SOUND_DEVICE_NAMES;
72 /**************************************************************************
73 * MIX_GetLineInfo [internal]
75 static DWORD MIX_GetLineInfo(WORD wDevID, LPMIXERLINE16 lpml, DWORD fdwInfo)
78 int mixer,i,j,devmask,recsrc,recmask;
80 TRACE(mmaux,"(%04X, %p, %lu);\n", wDevID, lpml, fdwInfo);
81 if (lpml == NULL) return MMSYSERR_NOTENABLED;
82 if ((mixer = open(MIXER_DEV, O_RDWR)) < 0)
83 return MMSYSERR_NOTENABLED;
85 if (ioctl(mixer, SOUND_MIXER_READ_DEVMASK, &devmask) == -1) {
87 perror("ioctl mixer SOUND_MIXER_DEVMASK");
88 return MMSYSERR_NOTENABLED;
90 if (ioctl(mixer, SOUND_MIXER_READ_RECSRC, &recsrc) == -1) {
92 perror("ioctl mixer SOUND_MIXER_RECSRC");
93 return MMSYSERR_NOTENABLED;
95 if (ioctl(mixer, SOUND_MIXER_READ_RECMASK, &recmask) == -1) {
97 perror("ioctl mixer SOUND_MIXER_RECMASK");
98 return MMSYSERR_NOTENABLED;
100 lpml->cbStruct = sizeof(MIXERLINE16);
101 /* FIXME: set all the variables correctly... the lines below
104 lpml->fdwLine = MIXERLINE_LINEF_ACTIVE;
107 switch (fdwInfo & MIXER_GETLINEINFOF_QUERYMASK) {
108 case MIXER_GETLINEINFOF_DESTINATION:
109 /* FIXME: Linux doesn't seem to support multiple outputs?
110 * So we have only one outputtype, Speaker.
112 lpml->dwComponentType = MIXERLINE_COMPONENTTYPE_DST_SPEAKERS;
113 /* we have all connections found in the devmask */
114 lpml->cConnections = 0;
116 if (devmask & (1<<j))
117 lpml->cConnections++;
119 case MIXER_GETLINEINFOF_SOURCE:
120 for (i=j=0;j<31;j++) {
121 if (devmask & (1<<j)) {
122 if (lpml->dwSource == i)
127 strcpy(lpml->szShortName,sdlabels[i]);
128 strcpy(lpml->szName,sdnames[i]);
131 case SOUND_MIXER_SYNTH:
132 lpml->dwComponentType = MIXERLINE_COMPONENTTYPE_SRC_SYNTHESIZER;
133 lpml->fdwLine |= MIXERLINE_LINEF_SOURCE;
136 lpml->dwComponentType = MIXERLINE_COMPONENTTYPE_SRC_COMPACTDISC;
137 lpml->fdwLine |= MIXERLINE_LINEF_SOURCE;
139 case SOUND_MIXER_LINE:
140 lpml->dwComponentType = MIXERLINE_COMPONENTTYPE_SRC_LINE;
141 lpml->fdwLine |= MIXERLINE_LINEF_SOURCE;
143 case SOUND_MIXER_MIC:
144 lpml->dwComponentType = MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE;
145 lpml->fdwLine |= MIXERLINE_LINEF_SOURCE;
147 case SOUND_MIXER_PCM:
148 lpml->dwComponentType = MIXERLINE_COMPONENTTYPE_SRC_WAVEOUT;
149 lpml->fdwLine |= MIXERLINE_LINEF_SOURCE;
152 ERR(mmaux,"Mixertype %d not handle.\n",i);
156 case MIXER_GETLINEINFOF_LINEID:
157 FIXME(mmaux,"_LINEID (%ld) not implemented yet.\n",lpml->dwLineID);
159 case MIXER_GETLINEINFOF_COMPONENTTYPE:
160 FIXME(mmaux," _COMPONENTTYPE not implemented yet.\n");
162 case MIXER_GETLINEINFOF_TARGETTYPE:
163 FIXME(mmaux,"_TARGETTYPE not implemented yet.\n");
166 lpml->Target.dwType = MIXERLINE_TARGETTYPE_AUX;
168 return MMSYSERR_NOERROR;
170 return MMSYSERR_NOTENABLED;
174 /**************************************************************************
175 * MIX_GetLineInfo [internal]
177 static DWORD MIX_Open(WORD wDevID, LPMIXEROPENDESC lpmod, DWORD flags)
181 TRACE(mmaux,"(%04X, %p, %lu);\n",wDevID,lpmod,flags);
182 if (lpmod == NULL) return MMSYSERR_NOTENABLED;
183 /* hmm. We don't keep the mixer device open. So just pretend it works */
184 return MMSYSERR_NOERROR;
186 return MMSYSERR_NOTENABLED;
190 /**************************************************************************
191 * mixMessage [sample driver]
193 DWORD WINAPI mixMessage(WORD wDevID, WORD wMsg, DWORD dwUser,
194 DWORD dwParam1, DWORD dwParam2)
196 TRACE(mmaux,"(%04X, %04X, %08lX, %08lX, %08lX);\n",
197 wDevID, wMsg, dwUser, dwParam1, dwParam2);
199 case MXDM_GETDEVCAPS:
200 return MIX_GetDevCaps(wDevID,(LPMIXERCAPS16)dwParam1,dwParam2);
201 case MXDM_GETLINEINFO:
202 return MIX_GetLineInfo(wDevID,(LPMIXERLINE16)dwParam1,dwParam2);
203 case MXDM_GETNUMDEVS:
204 TRACE(mmsys,"return 1;\n");
207 return MIX_Open(wDevID,(LPMIXEROPENDESC)dwParam1,dwParam2);
209 WARN(mmaux,"unknown message %d!\n",wMsg);
211 return MMSYSERR_NOTSUPPORTED;