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
;