4 * Copyright (c) 2004 Robert Reif
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
23 * add interactive tests
31 #include "wine/test.h"
37 #include "winmm_test.h"
39 static const char * line_flags(DWORD fdwLine
)
41 static char flags
[100];
44 if (fdwLine
&MIXERLINE_LINEF_ACTIVE
) {
45 strcat(flags
,"MIXERLINE_LINEF_ACTIVE");
48 if (fdwLine
&MIXERLINE_LINEF_DISCONNECTED
) {
52 strcat(flags
,"MIXERLINE_LINEF_DISCONNECTED");
56 if (fdwLine
&MIXERLINE_LINEF_SOURCE
) {
60 strcat(flags
,"MIXERLINE_LINEF_SOURCE");
66 static const char * component_type(DWORD dwComponentType
)
68 #define TYPE_TO_STR(x) case x: return #x
69 switch (dwComponentType
) {
70 TYPE_TO_STR(MIXERLINE_COMPONENTTYPE_DST_UNDEFINED
);
71 TYPE_TO_STR(MIXERLINE_COMPONENTTYPE_DST_DIGITAL
);
72 TYPE_TO_STR(MIXERLINE_COMPONENTTYPE_DST_LINE
);
73 TYPE_TO_STR(MIXERLINE_COMPONENTTYPE_DST_MONITOR
);
74 TYPE_TO_STR(MIXERLINE_COMPONENTTYPE_DST_SPEAKERS
);
75 TYPE_TO_STR(MIXERLINE_COMPONENTTYPE_DST_HEADPHONES
);
76 TYPE_TO_STR(MIXERLINE_COMPONENTTYPE_DST_TELEPHONE
);
77 TYPE_TO_STR(MIXERLINE_COMPONENTTYPE_DST_WAVEIN
);
78 TYPE_TO_STR(MIXERLINE_COMPONENTTYPE_DST_VOICEIN
);
79 TYPE_TO_STR(MIXERLINE_COMPONENTTYPE_SRC_UNDEFINED
);
80 TYPE_TO_STR(MIXERLINE_COMPONENTTYPE_SRC_DIGITAL
);
81 TYPE_TO_STR(MIXERLINE_COMPONENTTYPE_SRC_LINE
);
82 TYPE_TO_STR(MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE
);
83 TYPE_TO_STR(MIXERLINE_COMPONENTTYPE_SRC_SYNTHESIZER
);
84 TYPE_TO_STR(MIXERLINE_COMPONENTTYPE_SRC_COMPACTDISC
);
85 TYPE_TO_STR(MIXERLINE_COMPONENTTYPE_SRC_TELEPHONE
);
86 TYPE_TO_STR(MIXERLINE_COMPONENTTYPE_SRC_PCSPEAKER
);
87 TYPE_TO_STR(MIXERLINE_COMPONENTTYPE_SRC_WAVEOUT
);
88 TYPE_TO_STR(MIXERLINE_COMPONENTTYPE_SRC_AUXILIARY
);
89 TYPE_TO_STR(MIXERLINE_COMPONENTTYPE_SRC_ANALOG
);
95 static const char * target_type(DWORD dwType
)
97 #define TYPE_TO_STR(x) case x: return #x
99 TYPE_TO_STR(MIXERLINE_TARGETTYPE_UNDEFINED
);
100 TYPE_TO_STR(MIXERLINE_TARGETTYPE_WAVEOUT
);
101 TYPE_TO_STR(MIXERLINE_TARGETTYPE_WAVEIN
);
102 TYPE_TO_STR(MIXERLINE_TARGETTYPE_MIDIOUT
);
103 TYPE_TO_STR(MIXERLINE_TARGETTYPE_MIDIIN
);
104 TYPE_TO_STR(MIXERLINE_TARGETTYPE_AUX
);
110 static const char * control_type(DWORD dwControlType
)
112 #define TYPE_TO_STR(x) case x: return #x
113 switch (dwControlType
) {
114 TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_CUSTOM
);
115 TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_BOOLEANMETER
);
116 TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_SIGNEDMETER
);
117 TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_PEAKMETER
);
118 TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_UNSIGNEDMETER
);
119 TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_BOOLEAN
);
120 TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_ONOFF
);
121 TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_MUTE
);
122 TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_MONO
);
123 TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_LOUDNESS
);
124 TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_STEREOENH
);
125 TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_BASS_BOOST
);
126 TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_BUTTON
);
127 TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_DECIBELS
);
128 TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_SIGNED
);
129 TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_UNSIGNED
);
130 TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_PERCENT
);
131 TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_SLIDER
);
132 TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_PAN
);
133 TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_QSOUNDPAN
);
134 TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_FADER
);
135 TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_VOLUME
);
136 TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_BASS
);
137 TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_TREBLE
);
138 TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_EQUALIZER
);
139 TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_SINGLESELECT
);
140 TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_MUX
);
141 TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_MULTIPLESELECT
);
142 TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_MIXER
);
143 TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_MICROTIME
);
144 TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_MILLITIME
);
150 static const char * control_flags(DWORD fdwControl
)
152 static char flags
[100];
155 if (fdwControl
&MIXERCONTROL_CONTROLF_UNIFORM
) {
156 strcat(flags
,"MIXERCONTROL_CONTROLF_UNIFORM");
159 if (fdwControl
&MIXERCONTROL_CONTROLF_MULTIPLE
) {
163 strcat(flags
,"MIXERCONTROL_CONTROLF_MULTIPLE");
167 if (fdwControl
&MIXERCONTROL_CONTROLF_DISABLED
) {
171 strcat(flags
,"MIXERCONTROL_CONTROLF_DISABLED");
177 static void mixer_test_controlA(HMIXER mix
, LPMIXERCONTROLA control
)
181 if ((control
->dwControlType
== MIXERCONTROL_CONTROLTYPE_VOLUME
) ||
182 (control
->dwControlType
== MIXERCONTROL_CONTROLTYPE_UNSIGNED
)) {
183 MIXERCONTROLDETAILS details
;
184 MIXERCONTROLDETAILS_UNSIGNED value
;
186 details
.cbStruct
= sizeof(MIXERCONTROLDETAILS
);
187 details
.dwControlID
= control
->dwControlID
;
188 details
.cChannels
= 1;
189 U(details
).cMultipleItems
= 0;
190 details
.paDetails
= &value
;
191 details
.cbDetails
= sizeof(value
);
193 /* read the current control value */
194 rc
=mixerGetControlDetails((HMIXEROBJ
)mix
,&details
,MIXER_GETCONTROLDETAILSF_VALUE
);
195 ok(rc
==MMSYSERR_NOERROR
,"mixerGetControlDetails(MIXER_GETCONTROLDETAILSF_VALUE): "
196 "MMSYSERR_NOERROR expected, got %s\n",
198 if (rc
==MMSYSERR_NOERROR
) {
199 MIXERCONTROLDETAILS new_details
;
200 MIXERCONTROLDETAILS_UNSIGNED new_value
;
202 if (winetest_interactive
)
203 trace(" Value=%d\n",value
.dwValue
);
205 if (value
.dwValue
+ control
->Metrics
.cSteps
< S1(control
->Bounds
).dwMaximum
)
206 new_value
.dwValue
= value
.dwValue
+ control
->Metrics
.cSteps
;
208 new_value
.dwValue
= value
.dwValue
- control
->Metrics
.cSteps
;
210 new_details
.cbStruct
= sizeof(MIXERCONTROLDETAILS
);
211 new_details
.dwControlID
= control
->dwControlID
;
212 new_details
.cChannels
= 1;
213 U(new_details
).cMultipleItems
= 0;
214 new_details
.paDetails
= &new_value
;
215 new_details
.cbDetails
= sizeof(new_value
);
217 /* change the control value by one step */
218 rc
=mixerSetControlDetails((HMIXEROBJ
)mix
,&new_details
,MIXER_SETCONTROLDETAILSF_VALUE
);
219 ok(rc
==MMSYSERR_NOERROR
,"mixerSetControlDetails(MIXER_SETCONTROLDETAILSF_VALUE): "
220 "MMSYSERR_NOERROR expected, got %s\n",
222 if (rc
==MMSYSERR_NOERROR
) {
223 MIXERCONTROLDETAILS ret_details
;
224 MIXERCONTROLDETAILS_UNSIGNED ret_value
;
226 ret_details
.cbStruct
= sizeof(MIXERCONTROLDETAILS
);
227 ret_details
.dwControlID
= control
->dwControlID
;
228 ret_details
.cChannels
= 1;
229 U(ret_details
).cMultipleItems
= 0;
230 ret_details
.paDetails
= &ret_value
;
231 ret_details
.cbDetails
= sizeof(ret_value
);
233 /* read back the new control value */
234 rc
=mixerGetControlDetails((HMIXEROBJ
)mix
,&ret_details
,MIXER_GETCONTROLDETAILSF_VALUE
);
235 ok(rc
==MMSYSERR_NOERROR
,"mixerGetControlDetails(MIXER_GETCONTROLDETAILSF_VALUE): "
236 "MMSYSERR_NOERROR expected, got %s\n",
238 if (rc
==MMSYSERR_NOERROR
) {
239 /* result may not match exactly because of rounding */
240 ok(abs(ret_value
.dwValue
-new_value
.dwValue
)<=1,
241 "Couldn't change value from %d to %d, returned %d\n",
242 value
.dwValue
,new_value
.dwValue
,ret_value
.dwValue
);
244 if (abs(ret_value
.dwValue
-new_value
.dwValue
)<=1) {
245 details
.cbStruct
= sizeof(MIXERCONTROLDETAILS
);
246 details
.dwControlID
= control
->dwControlID
;
247 details
.cChannels
= 1;
248 U(details
).cMultipleItems
= 0;
249 details
.paDetails
= &value
;
250 details
.cbDetails
= sizeof(value
);
252 /* restore original value */
253 rc
=mixerSetControlDetails((HMIXEROBJ
)mix
,&details
,MIXER_SETCONTROLDETAILSF_VALUE
);
254 ok(rc
==MMSYSERR_NOERROR
,"mixerSetControlDetails(MIXER_SETCONTROLDETAILSF_VALUE): "
255 "MMSYSERR_NOERROR expected, got %s\n",
261 } else if ((control
->dwControlType
== MIXERCONTROL_CONTROLTYPE_MUTE
) ||
262 (control
->dwControlType
== MIXERCONTROL_CONTROLTYPE_BOOLEAN
) ||
263 (control
->dwControlType
== MIXERCONTROL_CONTROLTYPE_BUTTON
)) {
264 MIXERCONTROLDETAILS details
;
265 MIXERCONTROLDETAILS_BOOLEAN value
;
267 details
.cbStruct
= sizeof(MIXERCONTROLDETAILS
);
268 details
.dwControlID
= control
->dwControlID
;
269 details
.cChannels
= 1;
270 U(details
).cMultipleItems
= 0;
271 details
.paDetails
= &value
;
272 details
.cbDetails
= sizeof(value
);
274 rc
=mixerGetControlDetails((HMIXEROBJ
)mix
,&details
,MIXER_GETCONTROLDETAILSF_VALUE
);
275 ok(rc
==MMSYSERR_NOERROR
,"mixerGetControlDetails(MIXER_GETCONTROLDETAILSF_VALUE): "
276 "MMSYSERR_NOERROR expected, got %s\n",
278 if (rc
==MMSYSERR_NOERROR
) {
279 MIXERCONTROLDETAILS new_details
;
280 MIXERCONTROLDETAILS_BOOLEAN new_value
;
282 if (winetest_interactive
)
283 trace(" Value=%d\n",value
.fValue
);
285 if (value
.fValue
== FALSE
)
286 new_value
.fValue
= TRUE
;
288 new_value
.fValue
= FALSE
;
290 new_details
.cbStruct
= sizeof(MIXERCONTROLDETAILS
);
291 new_details
.dwControlID
= control
->dwControlID
;
292 new_details
.cChannels
= 1;
293 U(new_details
).cMultipleItems
= 0;
294 new_details
.paDetails
= &new_value
;
295 new_details
.cbDetails
= sizeof(new_value
);
297 /* change the control value by one step */
298 rc
=mixerSetControlDetails((HMIXEROBJ
)mix
,&new_details
,MIXER_SETCONTROLDETAILSF_VALUE
);
299 ok(rc
==MMSYSERR_NOERROR
,"mixerSetControlDetails(MIXER_SETCONTROLDETAILSF_VALUE): "
300 "MMSYSERR_NOERROR expected, got %s\n",
302 if (rc
==MMSYSERR_NOERROR
) {
303 MIXERCONTROLDETAILS ret_details
;
304 MIXERCONTROLDETAILS_BOOLEAN ret_value
;
306 ret_details
.cbStruct
= sizeof(MIXERCONTROLDETAILS
);
307 ret_details
.dwControlID
= control
->dwControlID
;
308 ret_details
.cChannels
= 1;
309 U(ret_details
).cMultipleItems
= 0;
310 ret_details
.paDetails
= &ret_value
;
311 ret_details
.cbDetails
= sizeof(ret_value
);
313 /* read back the new control value */
314 rc
=mixerGetControlDetails((HMIXEROBJ
)mix
,&ret_details
,MIXER_GETCONTROLDETAILSF_VALUE
);
315 ok(rc
==MMSYSERR_NOERROR
,"mixerGetControlDetails(MIXER_GETCONTROLDETAILSF_VALUE): "
316 "MMSYSERR_NOERROR expected, got %s\n",
318 if (rc
==MMSYSERR_NOERROR
) {
319 /* result may not match exactly because of rounding */
320 ok(ret_value
.fValue
==new_value
.fValue
,
321 "Couldn't change value from %d to %d, returned %d\n",
322 value
.fValue
,new_value
.fValue
,ret_value
.fValue
);
324 if (ret_value
.fValue
==new_value
.fValue
) {
325 details
.cbStruct
= sizeof(MIXERCONTROLDETAILS
);
326 details
.dwControlID
= control
->dwControlID
;
327 details
.cChannels
= 1;
328 U(details
).cMultipleItems
= 0;
329 details
.paDetails
= &value
;
330 details
.cbDetails
= sizeof(value
);
332 /* restore original value */
333 rc
=mixerSetControlDetails((HMIXEROBJ
)mix
,&details
,MIXER_SETCONTROLDETAILSF_VALUE
);
334 ok(rc
==MMSYSERR_NOERROR
,"mixerSetControlDetails(MIXER_SETCONTROLDETAILSF_VALUE): "
335 "MMSYSERR_NOERROR expected, got %s\n",
346 static void mixer_test_deviceA(int device
)
353 rc
=mixerGetDevCapsA(device
,0,sizeof(capsA
));
354 ok(rc
==MMSYSERR_INVALPARAM
,
355 "mixerGetDevCapsA: MMSYSERR_INVALPARAM expected, got %s\n",
358 rc
=mixerGetDevCapsA(device
,&capsA
,4);
359 ok(rc
==MMSYSERR_NOERROR
,
360 "mixerGetDevCapsA: MMSYSERR_NOERROR expected, got %s\n",
363 rc
=mixerGetDevCapsA(device
,&capsA
,sizeof(capsA
));
364 ok(rc
==MMSYSERR_NOERROR
,
365 "mixerGetDevCapsA: MMSYSERR_NOERROR expected, got %s\n",
368 if (winetest_interactive
) {
369 trace(" %d: \"%s\" %d.%d (%d:%d) destinations=%d\n", device
,
370 capsA
.szPname
, capsA
.vDriverVersion
>> 8,
371 capsA
.vDriverVersion
& 0xff,capsA
.wMid
,capsA
.wPid
,
372 capsA
.cDestinations
);
374 trace(" %d: \"%s\" %d.%d (%d:%d)\n", device
,
375 capsA
.szPname
, capsA
.vDriverVersion
>> 8,
376 capsA
.vDriverVersion
& 0xff,capsA
.wMid
,capsA
.wPid
);
379 rc
=mixerOpen(&mix
, device
, 0, 0, 0);
380 ok(rc
==MMSYSERR_NOERROR
,
381 "mixerOpen: MMSYSERR_NOERROR expected, got %s\n",mmsys_error(rc
));
382 if (rc
==MMSYSERR_NOERROR
) {
383 rc
=mixerOpen(&mix
, device
, 0, 0, CALLBACK_FUNCTION
);
384 ok(rc
==MMSYSERR_INVALFLAG
,
385 "mixerOpen: MMSYSERR_INVALFLAG expected, got %s\n", mmsys_error(rc
));
387 /* Shouldn't open without a valid HWND */
388 rc
=mixerOpen(&mix
, device
, 0, 0, CALLBACK_WINDOW
);
389 ok(rc
==MMSYSERR_INVALPARAM
,
390 "mixerOpen: MMSYSERR_INVALPARAM expected, got %s\n", mmsys_error(rc
));
393 for (d
=0;d
<capsA
.cDestinations
;d
++) {
394 MIXERLINEA mixerlineA
;
395 mixerlineA
.cbStruct
= 0;
396 mixerlineA
.dwDestination
=d
;
397 rc
=mixerGetLineInfoA((HMIXEROBJ
)mix
,&mixerlineA
,
398 MIXER_GETLINEINFOF_DESTINATION
);
399 ok(rc
==MMSYSERR_INVALPARAM
,
400 "mixerGetLineInfoA(MIXER_GETLINEINFOF_DESTINATION): "
401 "MMSYSERR_INVALPARAM expected, got %s\n",
404 mixerlineA
.cbStruct
= sizeof(mixerlineA
);
405 mixerlineA
.dwDestination
=capsA
.cDestinations
;
406 rc
=mixerGetLineInfoA((HMIXEROBJ
)mix
,&mixerlineA
,
407 MIXER_GETLINEINFOF_DESTINATION
);
408 ok(rc
==MMSYSERR_INVALPARAM
||rc
==MIXERR_INVALLINE
,
409 "mixerGetLineInfoA(MIXER_GETLINEINFOF_DESTINATION): "
410 "MMSYSERR_INVALPARAM or MIXERR_INVALLINE expected, got %s\n",
413 mixerlineA
.cbStruct
= sizeof(mixerlineA
);
414 mixerlineA
.dwDestination
=d
;
415 rc
=mixerGetLineInfoA((HMIXEROBJ
)mix
,0,
416 MIXER_GETLINEINFOF_DESTINATION
);
417 ok(rc
==MMSYSERR_INVALPARAM
,
418 "mixerGetLineInfoA(MIXER_GETLINEINFOF_DESTINATION): "
419 "MMSYSERR_INVALPARAM expected, got %s\n",
422 mixerlineA
.cbStruct
= sizeof(mixerlineA
);
423 mixerlineA
.dwDestination
=d
;
424 rc
=mixerGetLineInfoA((HMIXEROBJ
)mix
,&mixerlineA
,-1);
425 ok(rc
==MMSYSERR_INVALFLAG
,
426 "mixerGetLineInfoA(-1): MMSYSERR_INVALFLAG expected, got %s\n",
429 mixerlineA
.cbStruct
= sizeof(mixerlineA
);
430 mixerlineA
.dwDestination
=d
;
431 rc
=mixerGetLineInfoA((HMIXEROBJ
)mix
,&mixerlineA
,
432 MIXER_GETLINEINFOF_DESTINATION
);
433 ok(rc
==MMSYSERR_NOERROR
||rc
==MMSYSERR_NODRIVER
,
434 "mixerGetLineInfoA(MIXER_GETLINEINFOF_DESTINATION): "
435 "MMSYSERR_NOERROR expected, got %s\n",
437 if (rc
==MMSYSERR_NODRIVER
)
438 trace(" No Driver\n");
439 else if (rc
==MMSYSERR_NOERROR
) {
440 if (winetest_interactive
) {
441 trace(" %d: \"%s\" (%s) Destination=%d Source=%d\n",
442 d
,mixerlineA
.szShortName
, mixerlineA
.szName
,
443 mixerlineA
.dwDestination
,mixerlineA
.dwSource
);
444 trace(" LineID=%08x Channels=%d "
445 "Connections=%d Controls=%d\n",
446 mixerlineA
.dwLineID
,mixerlineA
.cChannels
,
447 mixerlineA
.cConnections
,mixerlineA
.cControls
);
448 trace(" State=0x%08x(%s)\n",
449 mixerlineA
.fdwLine
,line_flags(mixerlineA
.fdwLine
));
450 trace(" ComponentType=%s\n",
451 component_type(mixerlineA
.dwComponentType
));
453 target_type(mixerlineA
.Target
.dwType
));
454 trace(" Device=%d (%s) %d.%d (%d:%d)\n",
455 mixerlineA
.Target
.dwDeviceID
,
456 mixerlineA
.Target
.szPname
,
457 mixerlineA
.Target
.vDriverVersion
>> 8,
458 mixerlineA
.Target
.vDriverVersion
& 0xff,
459 mixerlineA
.Target
.wMid
, mixerlineA
.Target
.wPid
);
461 ns
=mixerlineA
.cConnections
;
463 mixerlineA
.cbStruct
= sizeof(mixerlineA
);
464 mixerlineA
.dwDestination
=d
;
465 mixerlineA
.dwSource
=s
;
466 rc
=mixerGetLineInfoA((HMIXEROBJ
)mix
,&mixerlineA
,
467 MIXER_GETLINEINFOF_SOURCE
);
468 ok(rc
==MMSYSERR_NOERROR
||rc
==MMSYSERR_NODRIVER
,
469 "mixerGetLineInfoA(MIXER_GETLINEINFOF_SOURCE): "
470 "MMSYSERR_NOERROR expected, got %s\n",
472 if (rc
==MMSYSERR_NODRIVER
)
473 trace(" No Driver\n");
474 else if (rc
==MMSYSERR_NOERROR
) {
475 LPMIXERCONTROLA array
;
476 MIXERLINECONTROLSA controls
;
477 if (winetest_interactive
) {
478 trace(" %d: \"%s\" (%s) Destination=%d Source=%d\n",
479 s
,mixerlineA
.szShortName
, mixerlineA
.szName
,
480 mixerlineA
.dwDestination
,mixerlineA
.dwSource
);
481 trace(" LineID=%08x Channels=%d "
482 "Connections=%d Controls=%d\n",
483 mixerlineA
.dwLineID
,mixerlineA
.cChannels
,
484 mixerlineA
.cConnections
,mixerlineA
.cControls
);
485 trace(" State=0x%08x(%s)\n",
486 mixerlineA
.fdwLine
,line_flags(mixerlineA
.fdwLine
));
487 trace(" ComponentType=%s\n",
488 component_type(mixerlineA
.dwComponentType
));
490 target_type(mixerlineA
.Target
.dwType
));
491 trace(" Device=%d (%s) %d.%d (%d:%d)\n",
492 mixerlineA
.Target
.dwDeviceID
,
493 mixerlineA
.Target
.szPname
,
494 mixerlineA
.Target
.vDriverVersion
>> 8,
495 mixerlineA
.Target
.vDriverVersion
& 0xff,
496 mixerlineA
.Target
.wMid
, mixerlineA
.Target
.wPid
);
498 if (mixerlineA
.cControls
) {
499 array
=HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,
500 mixerlineA
.cControls
*sizeof(MIXERCONTROLA
));
502 rc
=mixerGetLineControlsA((HMIXEROBJ
)mix
,0,
503 MIXER_GETLINECONTROLSF_ALL
);
504 ok(rc
==MMSYSERR_INVALPARAM
,
505 "mixerGetLineControlsA(MIXER_GETLINECONTROLSF_ALL): "
506 "MMSYSERR_INVALPARAM expected, got %s\n",
509 rc
=mixerGetLineControlsA((HMIXEROBJ
)mix
,&controls
,-1);
510 ok(rc
==MMSYSERR_INVALFLAG
||rc
==MMSYSERR_INVALPARAM
,
511 "mixerGetLineControlsA(-1): "
512 "MMSYSERR_INVALFLAG or MMSYSERR_INVALPARAM expected, got %s\n",
515 controls
.cbStruct
= sizeof(MIXERLINECONTROLSA
);
516 controls
.cControls
= mixerlineA
.cControls
;
517 controls
.dwLineID
= mixerlineA
.dwLineID
;
518 controls
.pamxctrl
= array
;
519 controls
.cbmxctrl
= sizeof(MIXERCONTROLA
);
521 /* FIXME: do MIXER_GETLINECONTROLSF_ONEBYID
522 * and MIXER_GETLINECONTROLSF_ONEBYTYPE
524 rc
=mixerGetLineControlsA((HMIXEROBJ
)mix
,&controls
,
525 MIXER_GETLINECONTROLSF_ALL
);
526 ok(rc
==MMSYSERR_NOERROR
,
527 "mixerGetLineControlsA(MIXER_GETLINECONTROLSF_ALL): "
528 "MMSYSERR_NOERROR expected, got %s\n",
530 if (rc
==MMSYSERR_NOERROR
) {
531 for(nc
=0;nc
<mixerlineA
.cControls
;nc
++) {
532 if (winetest_interactive
) {
533 trace(" %d: \"%s\" (%s) ControlID=%d\n", nc
,
534 array
[nc
].szShortName
,
535 array
[nc
].szName
, array
[nc
].dwControlID
);
536 trace(" ControlType=%s\n",
537 control_type(array
[nc
].dwControlType
));
538 trace(" Control=0x%08x(%s)\n",
539 array
[nc
].fdwControl
,
540 control_flags(array
[nc
].fdwControl
));
541 trace(" Items=%d Min=%d Max=%d Step=%d\n",
542 array
[nc
].cMultipleItems
,
543 S1(array
[nc
].Bounds
).dwMinimum
,
544 S1(array
[nc
].Bounds
).dwMaximum
,
545 array
[nc
].Metrics
.cSteps
);
548 mixer_test_controlA(mix
, &array
[nc
]);
552 HeapFree(GetProcessHeap(),0,array
);
560 ok(rc
==MMSYSERR_NOERROR
,
561 "mixerClose: MMSYSERR_BADDEVICEID expected, got %s\n",
566 static void mixer_test_controlW(HMIXER mix
, LPMIXERCONTROLW control
)
570 if ((control
->dwControlType
== MIXERCONTROL_CONTROLTYPE_VOLUME
) ||
571 (control
->dwControlType
== MIXERCONTROL_CONTROLTYPE_UNSIGNED
)) {
572 MIXERCONTROLDETAILS details
;
573 MIXERCONTROLDETAILS_UNSIGNED value
;
575 details
.cbStruct
= sizeof(MIXERCONTROLDETAILS
);
576 details
.dwControlID
= control
->dwControlID
;
577 details
.cChannels
= 1;
578 U(details
).cMultipleItems
= 0;
579 details
.paDetails
= &value
;
580 details
.cbDetails
= sizeof(value
);
582 /* read the current control value */
583 rc
=mixerGetControlDetails((HMIXEROBJ
)mix
,&details
,MIXER_GETCONTROLDETAILSF_VALUE
);
584 ok(rc
==MMSYSERR_NOERROR
,"mixerGetControlDetails(MIXER_GETCONTROLDETAILSF_VALUE): "
585 "MMSYSERR_NOERROR expected, got %s\n",
587 if (rc
==MMSYSERR_NOERROR
) {
588 MIXERCONTROLDETAILS new_details
;
589 MIXERCONTROLDETAILS_UNSIGNED new_value
;
591 if (winetest_interactive
)
592 trace(" Value=%d\n",value
.dwValue
);
594 if (value
.dwValue
+ control
->Metrics
.cSteps
< S1(control
->Bounds
).dwMaximum
)
595 new_value
.dwValue
= value
.dwValue
+ control
->Metrics
.cSteps
;
597 new_value
.dwValue
= value
.dwValue
- control
->Metrics
.cSteps
;
599 new_details
.cbStruct
= sizeof(MIXERCONTROLDETAILS
);
600 new_details
.dwControlID
= control
->dwControlID
;
601 new_details
.cChannels
= 1;
602 U(new_details
).cMultipleItems
= 0;
603 new_details
.paDetails
= &new_value
;
604 new_details
.cbDetails
= sizeof(new_value
);
606 /* change the control value by one step */
607 rc
=mixerSetControlDetails((HMIXEROBJ
)mix
,&new_details
,MIXER_SETCONTROLDETAILSF_VALUE
);
608 ok(rc
==MMSYSERR_NOERROR
,"mixerSetControlDetails(MIXER_SETCONTROLDETAILSF_VALUE): "
609 "MMSYSERR_NOERROR expected, got %s\n",
611 if (rc
==MMSYSERR_NOERROR
) {
612 MIXERCONTROLDETAILS ret_details
;
613 MIXERCONTROLDETAILS_UNSIGNED ret_value
;
615 ret_details
.cbStruct
= sizeof(MIXERCONTROLDETAILS
);
616 ret_details
.dwControlID
= control
->dwControlID
;
617 ret_details
.cChannels
= 1;
618 U(ret_details
).cMultipleItems
= 0;
619 ret_details
.paDetails
= &ret_value
;
620 ret_details
.cbDetails
= sizeof(ret_value
);
622 /* read back the new control value */
623 rc
=mixerGetControlDetails((HMIXEROBJ
)mix
,&ret_details
,MIXER_GETCONTROLDETAILSF_VALUE
);
624 ok(rc
==MMSYSERR_NOERROR
,"mixerGetControlDetails(MIXER_GETCONTROLDETAILSF_VALUE): "
625 "MMSYSERR_NOERROR expected, got %s\n",
627 if (rc
==MMSYSERR_NOERROR
) {
628 /* result may not match exactly because of rounding */
629 ok(abs(ret_value
.dwValue
-new_value
.dwValue
)<=1,
630 "Couldn't change value from %d to %d, returned %d\n",
631 value
.dwValue
,new_value
.dwValue
,ret_value
.dwValue
);
633 if (abs(ret_value
.dwValue
-new_value
.dwValue
)<=1) {
634 details
.cbStruct
= sizeof(MIXERCONTROLDETAILS
);
635 details
.dwControlID
= control
->dwControlID
;
636 details
.cChannels
= 1;
637 U(details
).cMultipleItems
= 0;
638 details
.paDetails
= &value
;
639 details
.cbDetails
= sizeof(value
);
641 /* restore original value */
642 rc
=mixerSetControlDetails((HMIXEROBJ
)mix
,&details
,MIXER_SETCONTROLDETAILSF_VALUE
);
643 ok(rc
==MMSYSERR_NOERROR
,"mixerSetControlDetails(MIXER_SETCONTROLDETAILSF_VALUE): "
644 "MMSYSERR_NOERROR expected, got %s\n",
650 } else if ((control
->dwControlType
== MIXERCONTROL_CONTROLTYPE_MUTE
) ||
651 (control
->dwControlType
== MIXERCONTROL_CONTROLTYPE_BOOLEAN
) ||
652 (control
->dwControlType
== MIXERCONTROL_CONTROLTYPE_BUTTON
)) {
653 MIXERCONTROLDETAILS details
;
654 MIXERCONTROLDETAILS_BOOLEAN value
;
656 details
.cbStruct
= sizeof(MIXERCONTROLDETAILS
);
657 details
.dwControlID
= control
->dwControlID
;
658 details
.cChannels
= 1;
659 U(details
).cMultipleItems
= 0;
660 details
.paDetails
= &value
;
661 details
.cbDetails
= sizeof(value
);
663 rc
=mixerGetControlDetails((HMIXEROBJ
)mix
,&details
,MIXER_GETCONTROLDETAILSF_VALUE
);
664 ok(rc
==MMSYSERR_NOERROR
,"mixerGetControlDetails(MIXER_GETCONTROLDETAILSF_VALUE): "
665 "MMSYSERR_NOERROR expected, got %s\n",
667 if (rc
==MMSYSERR_NOERROR
) {
668 MIXERCONTROLDETAILS new_details
;
669 MIXERCONTROLDETAILS_BOOLEAN new_value
;
671 if (winetest_interactive
)
672 trace(" Value=%d\n",value
.fValue
);
674 if (value
.fValue
== FALSE
)
675 new_value
.fValue
= TRUE
;
677 new_value
.fValue
= FALSE
;
679 new_details
.cbStruct
= sizeof(MIXERCONTROLDETAILS
);
680 new_details
.dwControlID
= control
->dwControlID
;
681 new_details
.cChannels
= 1;
682 U(new_details
).cMultipleItems
= 0;
683 new_details
.paDetails
= &new_value
;
684 new_details
.cbDetails
= sizeof(new_value
);
686 /* change the control value by one step */
687 rc
=mixerSetControlDetails((HMIXEROBJ
)mix
,&new_details
,MIXER_SETCONTROLDETAILSF_VALUE
);
688 ok(rc
==MMSYSERR_NOERROR
,"mixerSetControlDetails(MIXER_SETCONTROLDETAILSF_VALUE): "
689 "MMSYSERR_NOERROR expected, got %s\n",
691 if (rc
==MMSYSERR_NOERROR
) {
692 MIXERCONTROLDETAILS ret_details
;
693 MIXERCONTROLDETAILS_BOOLEAN ret_value
;
695 ret_details
.cbStruct
= sizeof(MIXERCONTROLDETAILS
);
696 ret_details
.dwControlID
= control
->dwControlID
;
697 ret_details
.cChannels
= 1;
698 U(ret_details
).cMultipleItems
= 0;
699 ret_details
.paDetails
= &ret_value
;
700 ret_details
.cbDetails
= sizeof(ret_value
);
702 /* read back the new control value */
703 rc
=mixerGetControlDetails((HMIXEROBJ
)mix
,&ret_details
,MIXER_GETCONTROLDETAILSF_VALUE
);
704 ok(rc
==MMSYSERR_NOERROR
,"mixerGetControlDetails(MIXER_GETCONTROLDETAILSF_VALUE): "
705 "MMSYSERR_NOERROR expected, got %s\n",
707 if (rc
==MMSYSERR_NOERROR
) {
708 /* result may not match exactly because of rounding */
709 ok(ret_value
.fValue
==new_value
.fValue
,
710 "Couldn't change value from %d to %d, returned %d\n",
711 value
.fValue
,new_value
.fValue
,ret_value
.fValue
);
713 if (ret_value
.fValue
==new_value
.fValue
) {
714 details
.cbStruct
= sizeof(MIXERCONTROLDETAILS
);
715 details
.dwControlID
= control
->dwControlID
;
716 details
.cChannels
= 1;
717 U(details
).cMultipleItems
= 0;
718 details
.paDetails
= &value
;
719 details
.cbDetails
= sizeof(value
);
721 /* restore original value */
722 rc
=mixerSetControlDetails((HMIXEROBJ
)mix
,&details
,MIXER_SETCONTROLDETAILSF_VALUE
);
723 ok(rc
==MMSYSERR_NOERROR
,"mixerSetControlDetails(MIXER_SETCONTROLDETAILSF_VALUE): "
724 "MMSYSERR_NOERROR expected, got %s\n",
735 static void mixer_test_deviceW(int device
)
741 char szShortName
[MIXER_SHORT_NAME_CHARS
];
742 char szName
[MIXER_LONG_NAME_CHARS
];
743 char szPname
[MAXPNAMELEN
];
745 rc
=mixerGetDevCapsW(device
,0,sizeof(capsW
));
746 ok(rc
==MMSYSERR_INVALPARAM
,
747 "mixerGetDevCapsW: MMSYSERR_INVALPARAM expected, got %s\n",
750 rc
=mixerGetDevCapsW(device
,&capsW
,4);
751 ok(rc
==MMSYSERR_NOERROR
,
752 "mixerGetDevCapsW: MMSYSERR_NOERROR expected, got %s\n",
755 rc
=mixerGetDevCapsW(device
,&capsW
,sizeof(capsW
));
756 ok(rc
==MMSYSERR_NOERROR
,
757 "mixerGetDevCapsW: MMSYSERR_NOERROR expected, got %s\n",
760 WideCharToMultiByte(CP_ACP
,0,capsW
.szPname
, MAXPNAMELEN
,szPname
,
761 MAXPNAMELEN
,NULL
,NULL
);
762 if (winetest_interactive
) {
763 trace(" %d: \"%s\" %d.%d (%d:%d) destinations=%d\n", device
,
764 szPname
, capsW
.vDriverVersion
>> 8,
765 capsW
.vDriverVersion
& 0xff,capsW
.wMid
,capsW
.wPid
,
766 capsW
.cDestinations
);
768 trace(" %d: \"%s\" %d.%d (%d:%d)\n", device
,
769 szPname
, capsW
.vDriverVersion
>> 8,
770 capsW
.vDriverVersion
& 0xff,capsW
.wMid
,capsW
.wPid
);
774 rc
=mixerOpen(&mix
, device
, 0, 0, 0);
775 ok(rc
==MMSYSERR_NOERROR
,
776 "mixerOpen: MMSYSERR_BADDEVICEID expected, got %s\n",mmsys_error(rc
));
777 if (rc
==MMSYSERR_NOERROR
) {
778 rc
=mixerOpen(&mix
, device
, 0, 0, CALLBACK_FUNCTION
);
779 ok(rc
==MMSYSERR_INVALFLAG
,
780 "mixerOpen: MMSYSERR_INVALFLAG expected, got %s\n", mmsys_error(rc
));
782 /* Shouldn't open without a valid HWND */
783 rc
=mixerOpen(&mix
, device
, 0, 0, CALLBACK_WINDOW
);
784 ok(rc
==MMSYSERR_INVALPARAM
,
785 "mixerOpen: MMSYSERR_INVALPARAM expected, got %s\n", mmsys_error(rc
));
787 for (d
=0;d
<capsW
.cDestinations
;d
++) {
788 MIXERLINEW mixerlineW
;
789 mixerlineW
.cbStruct
= 0;
790 mixerlineW
.dwDestination
=d
;
791 rc
=mixerGetLineInfoW((HMIXEROBJ
)mix
,&mixerlineW
,
792 MIXER_GETLINEINFOF_DESTINATION
);
793 ok(rc
==MMSYSERR_INVALPARAM
,
794 "mixerGetLineInfoW(MIXER_GETLINEINFOF_DESTINATION): "
795 "MMSYSERR_INVALPARAM expected, got %s\n",
798 mixerlineW
.cbStruct
= sizeof(mixerlineW
);
799 mixerlineW
.dwDestination
=capsW
.cDestinations
;
800 rc
=mixerGetLineInfoW((HMIXEROBJ
)mix
,&mixerlineW
,
801 MIXER_GETLINEINFOF_DESTINATION
);
802 ok(rc
==MMSYSERR_INVALPARAM
||rc
==MIXERR_INVALLINE
,
803 "mixerGetLineInfoW(MIXER_GETLINEINFOF_DESTINATION): "
804 "MMSYSERR_INVALPARAM or MIXERR_INVALLINE expected, got %s\n",
807 mixerlineW
.cbStruct
= sizeof(mixerlineW
);
808 mixerlineW
.dwDestination
=d
;
809 rc
=mixerGetLineInfoW((HMIXEROBJ
)mix
,0,
810 MIXER_GETLINEINFOF_DESTINATION
);
811 ok(rc
==MMSYSERR_INVALPARAM
,
812 "mixerGetLineInfoW(MIXER_GETLINEINFOF_DESTINATION): "
813 "MMSYSERR_INVALPARAM expected, got %s\n",
816 mixerlineW
.cbStruct
= sizeof(mixerlineW
);
817 mixerlineW
.dwDestination
=d
;
818 rc
=mixerGetLineInfoW((HMIXEROBJ
)mix
,&mixerlineW
,-1);
819 ok(rc
==MMSYSERR_INVALFLAG
,
820 "mixerGetLineInfoW(-1): MMSYSERR_INVALFLAG expected, got %s\n",
823 mixerlineW
.cbStruct
= sizeof(mixerlineW
);
824 mixerlineW
.dwDestination
=d
;
825 rc
=mixerGetLineInfoW((HMIXEROBJ
)mix
,&mixerlineW
,
826 MIXER_GETLINEINFOF_DESTINATION
);
827 ok(rc
==MMSYSERR_NOERROR
||rc
==MMSYSERR_NODRIVER
,
828 "mixerGetLineInfoW(MIXER_GETLINEINFOF_DESTINATION): "
829 "MMSYSERR_NOERROR expected, got %s\n",
831 if (rc
==MMSYSERR_NODRIVER
)
832 trace(" No Driver\n");
833 else if (rc
==MMSYSERR_NOERROR
&& winetest_interactive
) {
834 WideCharToMultiByte(CP_ACP
,0,mixerlineW
.szShortName
,
835 MIXER_SHORT_NAME_CHARS
,szShortName
,
836 MIXER_SHORT_NAME_CHARS
,NULL
,NULL
);
837 WideCharToMultiByte(CP_ACP
,0,mixerlineW
.szName
,
838 MIXER_LONG_NAME_CHARS
,szName
,
839 MIXER_LONG_NAME_CHARS
,NULL
,NULL
);
840 WideCharToMultiByte(CP_ACP
,0,mixerlineW
.Target
.szPname
,
842 MAXPNAMELEN
,NULL
, NULL
);
843 trace(" %d: \"%s\" (%s) Destination=%d Source=%d\n",
844 d
,szShortName
,szName
,
845 mixerlineW
.dwDestination
,mixerlineW
.dwSource
);
846 trace(" LineID=%08x Channels=%d "
847 "Connections=%d Controls=%d\n",
848 mixerlineW
.dwLineID
,mixerlineW
.cChannels
,
849 mixerlineW
.cConnections
,mixerlineW
.cControls
);
850 trace(" State=0x%08x(%s)\n",
851 mixerlineW
.fdwLine
,line_flags(mixerlineW
.fdwLine
));
852 trace(" ComponentType=%s\n",
853 component_type(mixerlineW
.dwComponentType
));
855 target_type(mixerlineW
.Target
.dwType
));
856 trace(" Device=%d (%s) %d.%d (%d:%d)\n",
857 mixerlineW
.Target
.dwDeviceID
,szPname
,
858 mixerlineW
.Target
.vDriverVersion
>> 8,
859 mixerlineW
.Target
.vDriverVersion
& 0xff,
860 mixerlineW
.Target
.wMid
, mixerlineW
.Target
.wPid
);
862 ns
=mixerlineW
.cConnections
;
864 mixerlineW
.cbStruct
= sizeof(mixerlineW
);
865 mixerlineW
.dwDestination
=d
;
866 mixerlineW
.dwSource
=s
;
867 rc
=mixerGetLineInfoW((HMIXEROBJ
)mix
,&mixerlineW
,
868 MIXER_GETLINEINFOF_SOURCE
);
869 ok(rc
==MMSYSERR_NOERROR
||rc
==MMSYSERR_NODRIVER
,
870 "mixerGetLineInfoW(MIXER_GETLINEINFOF_SOURCE): "
871 "MMSYSERR_NOERROR expected, got %s\n",
873 if (rc
==MMSYSERR_NODRIVER
)
874 trace(" No Driver\n");
875 else if (rc
==MMSYSERR_NOERROR
) {
876 LPMIXERCONTROLW array
;
877 MIXERLINECONTROLSW controls
;
878 if (winetest_interactive
) {
879 WideCharToMultiByte(CP_ACP
,0,mixerlineW
.szShortName
,
880 MIXER_SHORT_NAME_CHARS
,szShortName
,
881 MIXER_SHORT_NAME_CHARS
,NULL
,NULL
);
882 WideCharToMultiByte(CP_ACP
,0,mixerlineW
.szName
,
883 MIXER_LONG_NAME_CHARS
,szName
,
884 MIXER_LONG_NAME_CHARS
,NULL
,NULL
);
885 WideCharToMultiByte(CP_ACP
,0,mixerlineW
.Target
.szPname
,
887 MAXPNAMELEN
,NULL
, NULL
);
888 trace(" %d: \"%s\" (%s) Destination=%d Source=%d\n",
889 s
,szShortName
,szName
,
890 mixerlineW
.dwDestination
,mixerlineW
.dwSource
);
891 trace(" LineID=%08x Channels=%d "
892 "Connections=%d Controls=%d\n",
893 mixerlineW
.dwLineID
,mixerlineW
.cChannels
,
894 mixerlineW
.cConnections
,mixerlineW
.cControls
);
895 trace(" State=0x%08x(%s)\n",
896 mixerlineW
.fdwLine
,line_flags(mixerlineW
.fdwLine
));
897 trace(" ComponentType=%s\n",
898 component_type(mixerlineW
.dwComponentType
));
900 target_type(mixerlineW
.Target
.dwType
));
901 trace(" Device=%d (%s) %d.%d (%d:%d)\n",
902 mixerlineW
.Target
.dwDeviceID
,szPname
,
903 mixerlineW
.Target
.vDriverVersion
>> 8,
904 mixerlineW
.Target
.vDriverVersion
& 0xff,
905 mixerlineW
.Target
.wMid
, mixerlineW
.Target
.wPid
);
907 if (mixerlineW
.cControls
) {
908 array
=HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,
909 mixerlineW
.cControls
*sizeof(MIXERCONTROLW
));
911 rc
=mixerGetLineControlsW((HMIXEROBJ
)mix
,0,
912 MIXER_GETLINECONTROLSF_ALL
);
913 ok(rc
==MMSYSERR_INVALPARAM
,
914 "mixerGetLineControlsW(MIXER_GETLINECONTROLSF_ALL): "
915 "MMSYSERR_INVALPARAM expected, got %s\n",
917 rc
=mixerGetLineControlsW((HMIXEROBJ
)mix
,&controls
,
919 ok(rc
==MMSYSERR_INVALFLAG
||rc
==MMSYSERR_INVALPARAM
,
920 "mixerGetLineControlsA(-1): "
921 "MMSYSERR_INVALFLAG or MMSYSERR_INVALPARAM expected, got %s\n",
924 controls
.cbStruct
= sizeof(MIXERLINECONTROLSW
);
925 controls
.cControls
= mixerlineW
.cControls
;
926 controls
.dwLineID
= mixerlineW
.dwLineID
;
927 controls
.pamxctrl
= array
;
928 controls
.cbmxctrl
= sizeof(MIXERCONTROLW
);
930 /* FIXME: do MIXER_GETLINECONTROLSF_ONEBYID
931 * and MIXER_GETLINECONTROLSF_ONEBYTYPE
933 rc
=mixerGetLineControlsW((HMIXEROBJ
)mix
,&controls
,
934 MIXER_GETLINECONTROLSF_ALL
);
935 ok(rc
==MMSYSERR_NOERROR
,
936 "mixerGetLineControlsW(MIXER_GETLINECONTROLSF_ALL): "
937 "MMSYSERR_NOERROR expected, got %s\n",
939 if (rc
==MMSYSERR_NOERROR
) {
940 for(nc
=0;nc
<mixerlineW
.cControls
;nc
++) {
941 if (winetest_interactive
) {
942 WideCharToMultiByte(CP_ACP
,0,array
[nc
].szShortName
,
943 MIXER_SHORT_NAME_CHARS
,szShortName
,
944 MIXER_SHORT_NAME_CHARS
,NULL
,NULL
);
945 WideCharToMultiByte(CP_ACP
,0,array
[nc
].szName
,
946 MIXER_LONG_NAME_CHARS
,szName
,
947 MIXER_LONG_NAME_CHARS
,NULL
,NULL
);
948 trace(" %d: \"%s\" (%s) ControlID=%d\n", nc
,
949 szShortName
, szName
, array
[nc
].dwControlID
);
950 trace(" ControlType=%s\n",
951 control_type(array
[nc
].dwControlType
));
952 trace(" Control=0x%08x(%s)\n",
953 array
[nc
].fdwControl
,
954 control_flags(array
[nc
].fdwControl
));
955 trace(" Items=%d Min=%d Max=%d Step=%d\n",
956 array
[nc
].cMultipleItems
,
957 S1(array
[nc
].Bounds
).dwMinimum
,
958 S1(array
[nc
].Bounds
).dwMaximum
,
959 array
[nc
].Metrics
.cSteps
);
961 mixer_test_controlW(mix
, &array
[nc
]);
965 HeapFree(GetProcessHeap(),0,array
);
972 ok(rc
==MMSYSERR_NOERROR
,
973 "mixerClose: MMSYSERR_BADDEVICEID expected, got %s\n",
978 static void mixer_testsA(void)
985 trace("--- Testing ASCII functions ---\n");
987 ndev
=mixerGetNumDevs();
988 trace("found %d Mixer devices\n",ndev
);
990 rc
=mixerGetDevCapsA(ndev
+1,&capsA
,sizeof(capsA
));
991 ok(rc
==MMSYSERR_BADDEVICEID
,
992 "mixerGetDevCapsA: MMSYSERR_BADDEVICEID expected, got %s\n",
995 rc
=mixerOpen(&mix
, ndev
+1, 0, 0, 0);
996 ok(rc
==MMSYSERR_BADDEVICEID
,
997 "mixerOpen: MMSYSERR_BADDEVICEID expected, got %s\n",
1000 for (d
=0;d
<ndev
;d
++)
1001 mixer_test_deviceA(d
);
1004 static void mixer_testsW(void)
1011 trace("--- Testing WCHAR functions ---\n");
1013 ndev
=mixerGetNumDevs();
1014 trace("found %d Mixer devices\n",ndev
);
1016 rc
=mixerGetDevCapsW(ndev
+1,&capsW
,sizeof(capsW
));
1017 ok(rc
==MMSYSERR_BADDEVICEID
||rc
==MMSYSERR_NOTSUPPORTED
,
1018 "mixerGetDevCapsW: MMSYSERR_BADDEVICEID or MMSYSERR_NOTSUPPORTED "
1019 "expected, got %s\n", mmsys_error(rc
));
1020 if (rc
==MMSYSERR_NOTSUPPORTED
)
1023 rc
=mixerOpen(&mix
, ndev
+1, 0, 0, 0);
1024 ok(rc
==MMSYSERR_BADDEVICEID
,
1025 "mixerOpen: MMSYSERR_BADDEVICEID expected, got %s\n",
1028 for (d
=0;d
<ndev
;d
++)
1029 mixer_test_deviceW(d
);