2 * Sample MIXER Wine Driver for Linux
4 * Copyright 1997 Marcus Meissner
11 #include <sys/ioctl.h>
18 #include <linux/soundcard.h>
20 #include <machine/soundcard.h>
26 #define MIXER_DEV "/dev/mixer"
29 #define IOCTL(a,b,c) ioctl(a,b,&c)
31 #define IOCTL(a,b,c) (c = ioctl(a,b,c) )
35 /**************************************************************************
36 * MIX_GetDevCaps [internal]
38 static DWORD MIX_GetDevCaps(WORD wDevID, LPMIXERCAPS16 lpCaps, DWORD dwSize)
44 dprintf_mmaux(stddeb,"MIX_GetDevCaps(%04X, %p, %lu);\n", wDevID, lpCaps, dwSize);
45 if (lpCaps == NULL) return MMSYSERR_NOTENABLED;
46 if ((mixer = open(MIXER_DEV, O_RDWR)) < 0) {
47 dprintf_mmaux(stddeb,"MIX_GetDevCaps // mixer device not available !\n");
48 return MMSYSERR_NOTENABLED;
50 if (ioctl(mixer, SOUND_MIXER_INFO, &mi) == -1) {
52 perror("ioctl mixer SOUND_MIXER_INFO");
53 return MMSYSERR_NOTENABLED;
55 fprintf(stderr,"SOUND_MIXER_INFO returns { \"%s\",\"%s\" }\n",mi.id,mi.name);
58 lpCaps->vDriverVersion = 0x0100;
59 strcpy(lpCaps->szPname,mi.name);
60 if (ioctl(mixer, SOUND_MIXER_READ_DEVMASK, &mask) == -1) {
62 perror("ioctl mixer SOUND_MIXER_DEVMASK");
63 return MMSYSERR_NOTENABLED;
65 /* FIXME: can the Linux Mixer differ between multiple mixertargets? */
66 lpCaps->cDestinations = 1;
67 lpCaps->fdwSupport = 0; /* No bits defined yet */
70 return MMSYSERR_NOERROR;
72 return MMSYSERR_NOTENABLED;
77 static char *sdlabels[SOUND_MIXER_NRDEVICES] = SOUND_DEVICE_LABELS;
78 static char *sdnames[SOUND_MIXER_NRDEVICES] = SOUND_DEVICE_NAMES;
81 /**************************************************************************
82 * MIX_GetLineInfo [internal]
84 static DWORD MIX_GetLineInfo(WORD wDevID, LPMIXERLINE16 lpml, DWORD fdwInfo)
87 int mixer,i,j,devmask,recsrc,recmask;
89 dprintf_mmaux(stddeb,"MIX_GetDevLineInfo(%04X, %p, %lu);\n", wDevID, lpml, fdwInfo);
90 if (lpml == NULL) return MMSYSERR_NOTENABLED;
91 if ((mixer = open(MIXER_DEV, O_RDWR)) < 0)
92 return MMSYSERR_NOTENABLED;
94 if (ioctl(mixer, SOUND_MIXER_READ_DEVMASK, &devmask) == -1) {
96 perror("ioctl mixer SOUND_MIXER_DEVMASK");
97 return MMSYSERR_NOTENABLED;
99 if (ioctl(mixer, SOUND_MIXER_READ_RECSRC, &recsrc) == -1) {
101 perror("ioctl mixer SOUND_MIXER_RECSRC");
102 return MMSYSERR_NOTENABLED;
104 if (ioctl(mixer, SOUND_MIXER_READ_RECMASK, &recmask) == -1) {
106 perror("ioctl mixer SOUND_MIXER_RECMASK");
107 return MMSYSERR_NOTENABLED;
109 lpml->cbStruct = sizeof(MIXERLINE16);
110 /* FIXME: set all the variables correctly... the lines below
113 lpml->fdwLine = MIXERLINE_LINEF_ACTIVE;
116 switch (fdwInfo & MIXER_GETLINEINFOF_QUERYMASK) {
117 case MIXER_GETLINEINFOF_DESTINATION:
118 /* FIXME: Linux doesn't seem to support multiple outputs?
119 * So we have only one outputtype, Speaker.
121 lpml->dwComponentType = MIXERLINE_COMPONENTTYPE_DST_SPEAKERS;
122 /* we have all connections found in the devmask */
123 lpml->cConnections = 0;
125 if (devmask & (1<<j))
126 lpml->cConnections++;
128 case MIXER_GETLINEINFOF_SOURCE:
129 for (i=j=0;j<31;j++) {
130 if (devmask & (1<<j)) {
131 if (lpml->dwSource == i)
136 strcpy(lpml->szShortName,sdlabels[i]);
137 strcpy(lpml->szName,sdnames[i]);
140 case SOUND_MIXER_SYNTH:
141 lpml->dwComponentType = MIXERLINE_COMPONENTTYPE_SRC_SYNTHESIZER;
142 lpml->fdwLine |= MIXERLINE_LINEF_SOURCE;
145 lpml->dwComponentType = MIXERLINE_COMPONENTTYPE_SRC_COMPACTDISC;
146 lpml->fdwLine |= MIXERLINE_LINEF_SOURCE;
148 case SOUND_MIXER_LINE:
149 lpml->dwComponentType = MIXERLINE_COMPONENTTYPE_SRC_LINE;
150 lpml->fdwLine |= MIXERLINE_LINEF_SOURCE;
152 case SOUND_MIXER_MIC:
153 lpml->dwComponentType = MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE;
154 lpml->fdwLine |= MIXERLINE_LINEF_SOURCE;
156 case SOUND_MIXER_PCM:
157 lpml->dwComponentType = MIXERLINE_COMPONENTTYPE_SRC_WAVEOUT;
158 lpml->fdwLine |= MIXERLINE_LINEF_SOURCE;
161 fprintf(stderr,"MIX_GetLineInfo:mixertype %d not handle.\n",i);
165 case MIXER_GETLINEINFOF_LINEID:
166 fprintf(stderr,"MIX_GetLineInfo: _LINEID (%ld) not implemented yet.\n",lpml->dwLineID);
168 case MIXER_GETLINEINFOF_COMPONENTTYPE:
169 fprintf(stderr,"MIX_GetLineInfo: _COMPONENTTYPE not implemented yet.\n");
171 case MIXER_GETLINEINFOF_TARGETTYPE:
172 fprintf(stderr,"MIX_GetLineInfo: _TARGETTYPE not implemented yet.\n");
175 lpml->Target.dwType = MIXERLINE_TARGETTYPE_AUX;
177 return MMSYSERR_NOERROR;
179 return MMSYSERR_NOTENABLED;
183 /**************************************************************************
184 * MIX_GetLineInfo [internal]
186 static DWORD MIX_Open(WORD wDevID, LPMIXEROPENDESC lpmod, DWORD flags)
190 dprintf_mmaux(stddeb,"MIX_Open(%04X, %p, %lu);\n",wDevID,lpmod,flags);
191 if (lpmod == NULL) return MMSYSERR_NOTENABLED;
192 /* hmm. We don't keep the mixer device open. So just pretend it works */
193 return MMSYSERR_NOERROR;
195 return MMSYSERR_NOTENABLED;
199 /**************************************************************************
200 * mixMessage [sample driver]
202 DWORD mixMessage(WORD wDevID, WORD wMsg, DWORD dwUser,
203 DWORD dwParam1, DWORD dwParam2)
205 dprintf_mmaux(stddeb,"mixMessage(%04X, %04X, %08lX, %08lX, %08lX);\n",
206 wDevID, wMsg, dwUser, dwParam1, dwParam2);
208 case MXDM_GETDEVCAPS:
209 return MIX_GetDevCaps(wDevID,(LPMIXERCAPS16)dwParam1,dwParam2);
210 case MXDM_GETLINEINFO:
211 return MIX_GetLineInfo(wDevID,(LPMIXERLINE16)dwParam1,dwParam2);
212 case MXDM_GETNUMDEVS:
213 dprintf_mmsys(stddeb,"MIX_GetNumDevs() return 1;\n");
216 return MIX_Open(wDevID,(LPMIXEROPENDESC)dwParam1,dwParam2);
218 dprintf_mmaux(stddeb,"mixMessage // unknown message %d!\n",wMsg);
220 return MMSYSERR_NOTSUPPORTED;