ReactOS 0.4.15-dev-7928-g68a8619
winmm.c
Go to the documentation of this file.
1/* -*- tab-width: 8; c-basic-offset: 4 -*- */
2
3/*
4 * WINMM functions
5 *
6 * Copyright 1993 Martin Ayotte
7 * 1998-2002 Eric Pouech
8 *
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
13 *
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
18 *
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 */
23
24/*
25 * Eric POUECH :
26 * 98/9 added Win32 MCI support
27 * 99/4 added midiStream support
28 * 99/9 added support for loadable low level drivers
29 */
30
31/* TODO
32 * + it seems that some programs check what's installed in
33 * registry against the value returned by drivers. Wine is
34 * currently broken regarding this point.
35 * + check thread-safeness for MMSYSTEM and WINMM entry points
36 * + unicode entry points are badly supported (would require
37 * moving 32 bit drivers as Unicode as they are supposed to be)
38 * + allow joystick and timer external calls as we do for wave,
39 * midi, mixer and aux
40 */
41
42#include "winemm.h"
43
45
46/* ========================================================================
47 * G L O B A L S E T T I N G S
48 * ========================================================================*/
49
52
54
55/**************************************************************************
56 * WINMM_CreateIData [internal]
57 */
59{
60 hWinMM32Instance = hInstDLL;
63 return TRUE;
64}
65
66/**************************************************************************
67 * WINMM_DeleteIData [internal]
68 */
69static void WINMM_DeleteIData(void)
70{
72
73 /* FIXME: should also free content and resources allocated
74 * inside WINMM_IData */
77}
78
79/******************************************************************
80 * WINMM_LoadMMSystem
81 *
82 */
83static HANDLE (WINAPI *pGetModuleHandle16)(LPCSTR);
84static DWORD (WINAPI *pLoadLibrary16)(LPCSTR);
85
87{
88 /* 0 is not checked yet, -1 is not present, 1 is present */
89 static int loaded /* = 0 */;
90
91 if (loaded == 0)
92 {
93 HANDLE h = GetModuleHandleA("kernel32");
94 loaded = -1;
95 if (h)
96 {
97 pGetModuleHandle16 = (void*)GetProcAddress(h, "GetModuleHandle16");
98 pLoadLibrary16 = (void*)GetProcAddress(h, (LPCSTR)35); /* ordinal for LoadLibrary16 */
99 if (pGetModuleHandle16 && pLoadLibrary16 &&
100 (pGetModuleHandle16("MMSYSTEM.DLL") || pLoadLibrary16("MMSYSTEM.DLL")))
101 loaded = 1;
102 }
103 }
104 return loaded > 0;
105}
106
107/******************************************************************
108 * WINMM_ErrorToString
109 */
111{
112#define ERR_TO_STR(dev) case dev: return #dev
113 static char unknown[32];
114 switch (error) {
144 }
145 sprintf(unknown, "Unknown(0x%08x)", error);
146 return unknown;
147#undef ERR_TO_STR
148}
149
150/**************************************************************************
151 * DllMain (WINMM.init)
152 *
153 * WINMM DLL entry point
154 *
155 */
157{
158 TRACE("%p 0x%x %p\n", hInstDLL, fdwReason, fImpLoad);
159
160 switch (fdwReason) {
163
164 if (!WINMM_CreateIData(hInstDLL))
165 return FALSE;
166 if (!MMDRV_Init()) {
168 return FALSE;
169 }
170 break;
172 /* close all opened MCI drivers */
174 MMDRV_Exit();
175 /* There's no guarantee the drivers haven't already been unloaded on
176 * process shutdown.
177 */
178 if (!fImpLoad)
179 {
180 /* now unload all remaining drivers... */
182 }
183
185 break;
186 }
187 return TRUE;
188}
189
190/**************************************************************************
191 * WINMM_CheckCallback [internal]
192 */
194{
195 switch (fdwOpen & CALLBACK_TYPEMASK) {
196 case CALLBACK_NULL: /* dwCallback need not be NULL */
197 break;
198 case CALLBACK_WINDOW:
199 if (dwCallback && !IsWindow((HWND)dwCallback))
200 return MMSYSERR_INVALPARAM;
201 break;
202
204 /* a NULL cb is acceptable since w2k, MMSYSERR_INVALPARAM earlier */
205 if (mixer)
206 return MMSYSERR_INVALFLAG; /* since w2k, MMSYSERR_NOTSUPPORTED earlier */
207 break;
208 case CALLBACK_THREAD:
209 case CALLBACK_EVENT:
210 if (mixer) /* FIXME: mixer supports THREAD+EVENT since w2k */
211 return MMSYSERR_NOTSUPPORTED; /* w9X */
212 break;
213 default:
214 WARN("Unknown callback type %d\n", HIWORD(fdwOpen));
215 }
216 return MMSYSERR_NOERROR;
217}
218
219/**************************************************************************
220 * Mixer devices. New to Win95
221 */
222
223/**************************************************************************
224 * find out the real mixer ID depending on hmix (depends on dwFlags)
225 */
226static UINT MIXER_GetDev(HMIXEROBJ hmix, DWORD dwFlags, LPWINE_MIXER * lplpwm)
227{
228 LPWINE_MIXER lpwm = NULL;
229 UINT uRet = MMSYSERR_NOERROR;
230
231 switch (dwFlags & 0xF0000000ul) {
233 lpwm = (LPWINE_MIXER)MMDRV_Get(hmix, MMDRV_MIXER, TRUE);
234 break;
236 lpwm = (LPWINE_MIXER)MMDRV_Get(hmix, MMDRV_MIXER, FALSE);
237 break;
240 break;
243 break;
246 break;
249 break;
252 break;
255 break;
258 break;
261 break;
264 break;
265 default:
266 WARN("Unsupported flag (%08lx)\n", dwFlags & 0xF0000000ul);
267 lpwm = 0;
268 uRet = MMSYSERR_INVALFLAG;
269 break;
270 }
271 *lplpwm = lpwm;
272 if (lpwm == 0 && uRet == MMSYSERR_NOERROR)
273 uRet = MMSYSERR_INVALPARAM;
274 return uRet;
275}
276
277/**************************************************************************
278 * mixerGetNumDevs [WINMM.@]
279 */
281{
283}
284
285/**************************************************************************
286 * mixerGetDevCapsA [WINMM.@]
287 */
289{
290 MIXERCAPSW micW;
291 UINT ret;
292
293 if (lpCaps == NULL) return MMSYSERR_INVALPARAM;
294
295 ret = mixerGetDevCapsW(uDeviceID, &micW, sizeof(micW));
296
297 if (ret == MMSYSERR_NOERROR) {
298 MIXERCAPSA micA;
299 micA.wMid = micW.wMid;
300 micA.wPid = micW.wPid;
301 micA.vDriverVersion = micW.vDriverVersion;
302 WideCharToMultiByte( CP_ACP, 0, micW.szPname, -1, micA.szPname,
303 sizeof(micA.szPname), NULL, NULL );
304 micA.fdwSupport = micW.fdwSupport;
305 micA.cDestinations = micW.cDestinations;
306 memcpy(lpCaps, &micA, min(uSize, sizeof(micA)));
307 }
308 return ret;
309}
310
311/**************************************************************************
312 * mixerGetDevCapsW [WINMM.@]
313 */
315{
316 LPWINE_MLD wmld;
317
318 if (lpCaps == NULL) return MMSYSERR_INVALPARAM;
319
320 if ((wmld = MMDRV_Get((HANDLE)uDeviceID, MMDRV_MIXER, TRUE)) == NULL)
322
323 return MMDRV_Message(wmld, MXDM_GETDEVCAPS, (DWORD_PTR)lpCaps, uSize);
324}
325
326static void CALLBACK MIXER_WCallback(HMIXEROBJ hmx, UINT uMsg, DWORD_PTR dwInstance, DWORD_PTR dwParam, DWORD_PTR param2)
327{
328 HWND hWnd = (HWND)dwInstance;
329
330 if (!dwInstance)
331 return;
332
333 PostMessageW(hWnd, uMsg, (WPARAM)hmx, (LPARAM)dwParam);
334}
335
336/**************************************************************************
337 * mixerOpen [WINMM.@]
338 */
339UINT WINAPI mixerOpen(LPHMIXER lphMix, UINT uDeviceID, DWORD_PTR dwCallback,
340 DWORD_PTR dwInstance, DWORD fdwOpen)
341{
342 HANDLE hMix;
343 LPWINE_MLD wmld;
344 DWORD dwRet;
346
347 TRACE("(%p, %d, %08lx, %08lx, %08x)\n",
348 lphMix, uDeviceID, dwCallback, dwInstance, fdwOpen);
349
350 dwRet = WINMM_CheckCallback(dwCallback, fdwOpen, TRUE);
351 if(dwRet != MMSYSERR_NOERROR)
352 return dwRet;
353
354 mod.dwCallback = (DWORD_PTR)MIXER_WCallback;
355 if ((fdwOpen & CALLBACK_TYPEMASK) == CALLBACK_WINDOW)
356 mod.dwInstance = dwCallback;
357 else
358 mod.dwInstance = 0;
359
360 /* We're remapping to CALLBACK_FUNCTION because that's what old winmm is
361 * documented to do when opening the mixer driver.
362 * FIXME: Native supports CALLBACK_EVENT + CALLBACK_THREAD flags since w2k.
363 * FIXME: The non ALSA drivers ignore callback requests - bug.
364 */
365
366 wmld = MMDRV_Alloc(sizeof(WINE_MIXER), MMDRV_MIXER, &hMix, &fdwOpen,
367 &dwCallback, &dwInstance);
368 wmld->uDeviceID = uDeviceID;
369 mod.hmx = hMix;
370
372
373 if (dwRet != MMSYSERR_NOERROR) {
374 MMDRV_Free(hMix, wmld);
375 hMix = 0;
376 }
377 if (lphMix) *lphMix = hMix;
378 TRACE("=> %d hMixer=%p\n", dwRet, hMix);
379
380 return dwRet;
381}
382
383/**************************************************************************
384 * mixerClose [WINMM.@]
385 */
387{
388 LPWINE_MLD wmld;
389 DWORD dwRet;
390
391 TRACE("(%p)\n", hMix);
392
393 if ((wmld = MMDRV_Get(hMix, MMDRV_MIXER, FALSE)) == NULL) return MMSYSERR_INVALHANDLE;
394
395 dwRet = MMDRV_Close(wmld, MXDM_CLOSE);
396 MMDRV_Free(hMix, wmld);
397
398 return dwRet;
399}
400
401/**************************************************************************
402 * mixerGetID [WINMM.@]
403 */
404UINT WINAPI mixerGetID(HMIXEROBJ hmix, LPUINT lpid, DWORD fdwID)
405{
406 LPWINE_MIXER lpwm;
407 UINT uRet = MMSYSERR_NOERROR;
408
409 TRACE("(%p %p %08x)\n", hmix, lpid, fdwID);
410
411 if ((uRet = MIXER_GetDev(hmix, fdwID, &lpwm)) != MMSYSERR_NOERROR)
412 return uRet;
413
414 if (lpid)
415 *lpid = lpwm->mld.uDeviceID;
416
417 return uRet;
418}
419
420/**************************************************************************
421 * mixerGetControlDetailsW [WINMM.@]
422 */
424 DWORD fdwDetails)
425{
426 LPWINE_MIXER lpwm;
427 UINT uRet = MMSYSERR_NOERROR;
428
429 TRACE("(%p, %p, %08x)\n", hmix, lpmcdW, fdwDetails);
430
431 if ((uRet = MIXER_GetDev(hmix, fdwDetails, &lpwm)) != MMSYSERR_NOERROR)
432 return uRet;
433
434 if (lpmcdW == NULL || lpmcdW->cbStruct != sizeof(*lpmcdW))
435 return MMSYSERR_INVALPARAM;
436
437 return MMDRV_Message(&lpwm->mld, MXDM_GETCONTROLDETAILS, (DWORD_PTR)lpmcdW,
438 fdwDetails);
439}
440
441/**************************************************************************
442 * mixerGetControlDetailsA [WINMM.@]
443 */
445 DWORD fdwDetails)
446{
448
449 TRACE("(%p, %p, %08x)\n", hmix, lpmcdA, fdwDetails);
450
451 if (lpmcdA == NULL || lpmcdA->cbStruct != sizeof(*lpmcdA))
452 return MMSYSERR_INVALPARAM;
453
454 switch (fdwDetails & MIXER_GETCONTROLDETAILSF_QUERYMASK) {
456 /* can safely use A structure as it is, no string inside */
457 ret = mixerGetControlDetailsW(hmix, lpmcdA, fdwDetails);
458 break;
460 {
461 MIXERCONTROLDETAILS_LISTTEXTA *pDetailsA = lpmcdA->paDetails;
463 int size = max(1, lpmcdA->cChannels) * sizeof(MIXERCONTROLDETAILS_LISTTEXTW);
464 unsigned int i;
465
466 if (lpmcdA->u.cMultipleItems != 0) {
467 size *= lpmcdA->u.cMultipleItems;
468 }
469 pDetailsW = HeapAlloc(GetProcessHeap(), 0, size);
470 lpmcdA->paDetails = pDetailsW;
472 /* set up lpmcd->paDetails */
473 ret = mixerGetControlDetailsW(hmix, lpmcdA, fdwDetails);
474 /* copy from lpmcd->paDetails back to paDetailsW; */
475 if (ret == MMSYSERR_NOERROR) {
476 for (i = 0; i < lpmcdA->u.cMultipleItems * lpmcdA->cChannels; i++) {
477 pDetailsA->dwParam1 = pDetailsW->dwParam1;
478 pDetailsA->dwParam2 = pDetailsW->dwParam2;
479 WideCharToMultiByte( CP_ACP, 0, pDetailsW->szName, -1,
480 pDetailsA->szName,
481 sizeof(pDetailsA->szName), NULL, NULL );
482 pDetailsA++;
483 pDetailsW++;
484 }
485 pDetailsA -= lpmcdA->u.cMultipleItems * lpmcdA->cChannels;
486 pDetailsW -= lpmcdA->u.cMultipleItems * lpmcdA->cChannels;
487 }
488 HeapFree(GetProcessHeap(), 0, pDetailsW);
489 lpmcdA->paDetails = pDetailsA;
491 }
492 break;
493 default:
494 ERR("Unsupported fdwDetails=0x%08x\n", fdwDetails);
495 }
496
497 return ret;
498}
499
500/**************************************************************************
501 * mixerGetLineControlsA [WINMM.@]
502 */
504 DWORD fdwControls)
505{
507 DWORD ret;
508 unsigned int i;
509
510 TRACE("(%p, %p, %08x)\n", hmix, lpmlcA, fdwControls);
511
512 if (lpmlcA == NULL || lpmlcA->cbStruct != sizeof(*lpmlcA) ||
513 lpmlcA->cbmxctrl != sizeof(MIXERCONTROLA))
514 return MMSYSERR_INVALPARAM;
515
516 mlcW.cbStruct = sizeof(mlcW);
517 mlcW.dwLineID = lpmlcA->dwLineID;
518 mlcW.u.dwControlID = lpmlcA->u.dwControlID;
519 mlcW.u.dwControlType = lpmlcA->u.dwControlType;
520
521 /* Debugging on Windows shows for MIXER_GETLINECONTROLSF_ONEBYTYPE only,
522 the control count is assumed to be 1 - This is relied upon by a game,
523 "Dynomite Deluze" */
525 mlcW.cControls = 1;
526 } else {
527 mlcW.cControls = lpmlcA->cControls;
528 }
529 mlcW.cbmxctrl = sizeof(MIXERCONTROLW);
531 mlcW.cControls * mlcW.cbmxctrl);
532
533 ret = mixerGetLineControlsW(hmix, &mlcW, fdwControls);
534
535 if (ret == MMSYSERR_NOERROR) {
536 lpmlcA->dwLineID = mlcW.dwLineID;
537 lpmlcA->u.dwControlID = mlcW.u.dwControlID;
538 lpmlcA->u.dwControlType = mlcW.u.dwControlType;
539
540 for (i = 0; i < mlcW.cControls; i++) {
541 lpmlcA->pamxctrl[i].cbStruct = sizeof(MIXERCONTROLA);
542 lpmlcA->pamxctrl[i].dwControlID = mlcW.pamxctrl[i].dwControlID;
544 lpmlcA->pamxctrl[i].fdwControl = mlcW.pamxctrl[i].fdwControl;
547 lpmlcA->pamxctrl[i].szShortName,
548 sizeof(lpmlcA->pamxctrl[i].szShortName), NULL, NULL );
550 lpmlcA->pamxctrl[i].szName,
551 sizeof(lpmlcA->pamxctrl[i].szName), NULL, NULL );
552 /* sizeof(lpmlcA->pamxctrl[i].Bounds) ==
553 * sizeof(mlcW.pamxctrl[i].Bounds) */
554 memcpy(&lpmlcA->pamxctrl[i].Bounds, &mlcW.pamxctrl[i].Bounds,
555 sizeof(mlcW.pamxctrl[i].Bounds));
556 /* sizeof(lpmlcA->pamxctrl[i].Metrics) ==
557 * sizeof(mlcW.pamxctrl[i].Metrics) */
558 memcpy(&lpmlcA->pamxctrl[i].Metrics, &mlcW.pamxctrl[i].Metrics,
559 sizeof(mlcW.pamxctrl[i].Metrics));
560 }
561 }
562
563 HeapFree(GetProcessHeap(), 0, mlcW.pamxctrl);
564
565 return ret;
566}
567
568/**************************************************************************
569 * mixerGetLineControlsW [WINMM.@]
570 */
572 DWORD fdwControls)
573{
574 LPWINE_MIXER lpwm;
575 UINT uRet = MMSYSERR_NOERROR;
576
577 TRACE("(%p, %p, %08x)\n", hmix, lpmlcW, fdwControls);
578
579 if ((uRet = MIXER_GetDev(hmix, fdwControls, &lpwm)) != MMSYSERR_NOERROR)
580 return uRet;
581
582 if (lpmlcW == NULL || lpmlcW->cbStruct != sizeof(*lpmlcW))
583 return MMSYSERR_INVALPARAM;
584
585 return MMDRV_Message(&lpwm->mld, MXDM_GETLINECONTROLS, (DWORD_PTR)lpmlcW,
586 fdwControls);
587}
588
589/**************************************************************************
590 * mixerGetLineInfoW [WINMM.@]
591 */
592UINT WINAPI mixerGetLineInfoW(HMIXEROBJ hmix, LPMIXERLINEW lpmliW, DWORD fdwInfo)
593{
594 LPWINE_MIXER lpwm;
595 UINT uRet = MMSYSERR_NOERROR;
596
597 TRACE("(%p, %p, %08x)\n", hmix, lpmliW, fdwInfo);
598
599 if (lpmliW == NULL || lpmliW->cbStruct != sizeof(*lpmliW))
600 return MMSYSERR_INVALPARAM;
601
602 if ((uRet = MIXER_GetDev(hmix, fdwInfo, &lpwm)) != MMSYSERR_NOERROR)
603 return uRet;
604
605 return MMDRV_Message(&lpwm->mld, MXDM_GETLINEINFO, (DWORD_PTR)lpmliW,
606 fdwInfo);
607}
608
609/**************************************************************************
610 * mixerGetLineInfoA [WINMM.@]
611 */
613 DWORD fdwInfo)
614{
615 MIXERLINEW mliW;
616 UINT ret;
617
618 TRACE("(%p, %p, %08x)\n", hmix, lpmliA, fdwInfo);
619
620 if (lpmliA == NULL || lpmliA->cbStruct != sizeof(*lpmliA))
621 return MMSYSERR_INVALPARAM;
622
623 mliW.cbStruct = sizeof(mliW);
624 switch (fdwInfo & MIXER_GETLINEINFOF_QUERYMASK) {
626 mliW.dwComponentType = lpmliA->dwComponentType;
627 break;
629 mliW.dwDestination = lpmliA->dwDestination;
630 break;
632 mliW.dwLineID = lpmliA->dwLineID;
633 break;
635 mliW.dwDestination = lpmliA->dwDestination;
636 mliW.dwSource = lpmliA->dwSource;
637 break;
639 mliW.Target.dwType = lpmliA->Target.dwType;
640 mliW.Target.wMid = lpmliA->Target.wMid;
641 mliW.Target.wPid = lpmliA->Target.wPid;
642 mliW.Target.vDriverVersion = lpmliA->Target.vDriverVersion;
643 MultiByteToWideChar( CP_ACP, 0, lpmliA->Target.szPname, -1, mliW.Target.szPname, sizeof(mliW.Target.szPname)/sizeof(WCHAR));
644 break;
645 default:
646 WARN("Unsupported fdwControls=0x%08x\n", fdwInfo);
647 return MMSYSERR_INVALFLAG;
648 }
649
650 ret = mixerGetLineInfoW(hmix, &mliW, fdwInfo);
651
652 if(ret == MMSYSERR_NOERROR)
653 {
654 lpmliA->dwDestination = mliW.dwDestination;
655 lpmliA->dwSource = mliW.dwSource;
656 lpmliA->dwLineID = mliW.dwLineID;
657 lpmliA->fdwLine = mliW.fdwLine;
658 lpmliA->dwUser = mliW.dwUser;
659 lpmliA->dwComponentType = mliW.dwComponentType;
660 lpmliA->cChannels = mliW.cChannels;
661 lpmliA->cConnections = mliW.cConnections;
662 lpmliA->cControls = mliW.cControls;
663 WideCharToMultiByte( CP_ACP, 0, mliW.szShortName, -1, lpmliA->szShortName,
664 sizeof(lpmliA->szShortName), NULL, NULL);
665 WideCharToMultiByte( CP_ACP, 0, mliW.szName, -1, lpmliA->szName,
666 sizeof(lpmliA->szName), NULL, NULL );
667 lpmliA->Target.dwType = mliW.Target.dwType;
668 lpmliA->Target.dwDeviceID = mliW.Target.dwDeviceID;
669 lpmliA->Target.wMid = mliW.Target.wMid;
670 lpmliA->Target.wPid = mliW.Target.wPid;
671 lpmliA->Target.vDriverVersion = mliW.Target.vDriverVersion;
672 WideCharToMultiByte( CP_ACP, 0, mliW.Target.szPname, -1, lpmliA->Target.szPname,
673 sizeof(lpmliA->Target.szPname), NULL, NULL );
674 }
675 return ret;
676}
677
678/**************************************************************************
679 * mixerSetControlDetails [WINMM.@]
680 */
682 DWORD fdwDetails)
683{
684 LPWINE_MIXER lpwm;
685 UINT uRet = MMSYSERR_NOERROR;
686
687 TRACE("(%p, %p, %08x)\n", hmix, lpmcd, fdwDetails);
688
689 if ((uRet = MIXER_GetDev(hmix, fdwDetails, &lpwm)) != MMSYSERR_NOERROR)
690 return uRet;
691
692 return MMDRV_Message(&lpwm->mld, MXDM_SETCONTROLDETAILS, (DWORD_PTR)lpmcd,
693 fdwDetails);
694}
695
696/**************************************************************************
697 * mixerMessage [WINMM.@]
698 */
699DWORD WINAPI mixerMessage(HMIXER hmix, UINT uMsg, DWORD_PTR dwParam1, DWORD_PTR dwParam2)
700{
701 LPWINE_MLD wmld;
702
703 TRACE("(%p, %d, %08lx, %08lx): semi-stub?\n",
704 hmix, uMsg, dwParam1, dwParam2);
705
706 if ((wmld = MMDRV_Get(hmix, MMDRV_MIXER, FALSE)) == NULL)
708
709 return MMDRV_Message(wmld, uMsg, dwParam1, dwParam2);
710}
711
712/**************************************************************************
713 * auxGetNumDevs [WINMM.@]
714 */
716{
717 return MMDRV_GetNum(MMDRV_AUX);
718}
719
720/**************************************************************************
721 * auxGetDevCapsW [WINMM.@]
722 */
724{
725 LPWINE_MLD wmld;
726
727 TRACE("(%04lX, %p, %d) !\n", uDeviceID, lpCaps, uSize);
728
729 if (lpCaps == NULL) return MMSYSERR_INVALPARAM;
730
731 if ((wmld = MMDRV_Get((HANDLE)uDeviceID, MMDRV_AUX, TRUE)) == NULL)
733 return MMDRV_Message(wmld, AUXDM_GETDEVCAPS, (DWORD_PTR)lpCaps, uSize);
734}
735
736/**************************************************************************
737 * auxGetDevCapsA [WINMM.@]
738 */
740{
741 AUXCAPSW acW;
742 UINT ret;
743
744 if (lpCaps == NULL) return MMSYSERR_INVALPARAM;
745
746 ret = auxGetDevCapsW(uDeviceID, &acW, sizeof(acW));
747
748 if (ret == MMSYSERR_NOERROR) {
749 AUXCAPSA acA;
750 acA.wMid = acW.wMid;
751 acA.wPid = acW.wPid;
753 WideCharToMultiByte( CP_ACP, 0, acW.szPname, -1, acA.szPname,
754 sizeof(acA.szPname), NULL, NULL );
755 acA.wTechnology = acW.wTechnology;
756 acA.dwSupport = acW.dwSupport;
757 memcpy(lpCaps, &acA, min(uSize, sizeof(acA)));
758 }
759 return ret;
760}
761
762/**************************************************************************
763 * auxGetVolume [WINMM.@]
764 */
765UINT WINAPI auxGetVolume(UINT uDeviceID, DWORD* lpdwVolume)
766{
767 LPWINE_MLD wmld;
768
769 TRACE("(%04X, %p) !\n", uDeviceID, lpdwVolume);
770
771 if ((wmld = MMDRV_Get(UlongToHandle(uDeviceID), MMDRV_AUX, TRUE)) == NULL)
773 return MMDRV_Message(wmld, AUXDM_GETVOLUME, (DWORD_PTR)lpdwVolume, 0L);
774}
775
776/**************************************************************************
777 * auxSetVolume [WINMM.@]
778 */
779UINT WINAPI auxSetVolume(UINT uDeviceID, DWORD dwVolume)
780{
781 LPWINE_MLD wmld;
782
783 TRACE("(%04X, %u) !\n", uDeviceID, dwVolume);
784
785 if ((wmld = MMDRV_Get(UlongToHandle(uDeviceID), MMDRV_AUX, TRUE)) == NULL)
787 return MMDRV_Message(wmld, AUXDM_SETVOLUME, dwVolume, 0L);
788}
789
790/**************************************************************************
791 * auxOutMessage [WINMM.@]
792 */
793UINT WINAPI auxOutMessage(UINT uDeviceID, UINT uMessage, DWORD_PTR dw1, DWORD_PTR dw2)
794{
795 LPWINE_MLD wmld;
796
797 if ((wmld = MMDRV_Get(UlongToHandle(uDeviceID), MMDRV_AUX, TRUE)) == NULL)
799
800 return MMDRV_Message(wmld, uMessage, dw1, dw2);
801}
802
803/**************************************************************************
804 * midiOutGetNumDevs [WINMM.@]
805 */
807{
809}
810
811/**************************************************************************
812 * midiOutGetDevCapsW [WINMM.@]
813 */
815 UINT uSize)
816{
817 LPWINE_MLD wmld;
818
819 TRACE("(%lu, %p, %u);\n", uDeviceID, lpCaps, uSize);
820
821 if (lpCaps == NULL) return MMSYSERR_INVALPARAM;
822
823 if ((wmld = MMDRV_Get((HANDLE)uDeviceID, MMDRV_MIDIOUT, TRUE)) == NULL)
825
826 return MMDRV_Message(wmld, MODM_GETDEVCAPS, (DWORD_PTR)lpCaps, uSize);
827}
828
829/**************************************************************************
830 * midiOutGetDevCapsA [WINMM.@]
831 */
833 UINT uSize)
834{
835 MIDIOUTCAPSW mocW;
836 UINT ret;
837
838 if (lpCaps == NULL) return MMSYSERR_INVALPARAM;
839
840 ret = midiOutGetDevCapsW(uDeviceID, &mocW, sizeof(mocW));
841
842 if (ret == MMSYSERR_NOERROR) {
843 MIDIOUTCAPSA mocA;
844 mocA.wMid = mocW.wMid;
845 mocA.wPid = mocW.wPid;
846 mocA.vDriverVersion = mocW.vDriverVersion;
847 WideCharToMultiByte( CP_ACP, 0, mocW.szPname, -1, mocA.szPname,
848 sizeof(mocA.szPname), NULL, NULL );
849 mocA.wTechnology = mocW.wTechnology;
850 mocA.wVoices = mocW.wVoices;
851 mocA.wNotes = mocW.wNotes;
852 mocA.wChannelMask = mocW.wChannelMask;
853 mocA.dwSupport = mocW.dwSupport;
854 memcpy(lpCaps, &mocA, min(uSize, sizeof(mocA)));
855 }
856 return ret;
857}
858
859/**************************************************************************
860 * midiOutGetErrorTextA [WINMM.@]
861 * midiInGetErrorTextA [WINMM.@]
862 */
864{
865 UINT ret;
866
867 if (lpText == NULL) ret = MMSYSERR_INVALPARAM;
868 else if (uSize == 0) ret = MMSYSERR_NOERROR;
869 else
870 {
871 LPWSTR xstr = HeapAlloc(GetProcessHeap(), 0, uSize * sizeof(WCHAR));
872 if (!xstr) ret = MMSYSERR_NOMEM;
873 else
874 {
875 ret = midiOutGetErrorTextW(uError, xstr, uSize);
876 if (ret == MMSYSERR_NOERROR)
877 WideCharToMultiByte(CP_ACP, 0, xstr, -1, lpText, uSize, NULL, NULL);
878 HeapFree(GetProcessHeap(), 0, xstr);
879 }
880 }
881 return ret;
882}
883
884/**************************************************************************
885 * midiOutGetErrorTextW [WINMM.@]
886 * midiInGetErrorTextW [WINMM.@]
887 */
889{
891
892 if (lpText == NULL) ret = MMSYSERR_INVALPARAM;
893 else if (uSize == 0) ret = MMSYSERR_NOERROR;
894 else if (
895 /* test has been removed because MMSYSERR_BASE is 0, and gcc did emit
896 * a warning for the test was always true */
897 (/*uError >= MMSYSERR_BASE && */ uError <= MMSYSERR_LASTERROR) ||
898 (uError >= MIDIERR_BASE && uError <= MIDIERR_LASTERROR)) {
899 if (LoadStringW(hWinMM32Instance, uError, lpText, uSize) > 0) {
901 }
902 }
903 return ret;
904}
905
906/**************************************************************************
907 * MIDI_OutAlloc [internal]
908 */
909static LPWINE_MIDI MIDI_OutAlloc(HMIDIOUT* lphMidiOut, DWORD_PTR* lpdwCallback,
910 DWORD_PTR* lpdwInstance, LPDWORD lpdwFlags,
911 DWORD cIDs, MIDIOPENSTRMID* lpIDs)
912{
913 HANDLE hMidiOut;
914 LPWINE_MIDI lpwm;
915 UINT size;
916
917 size = sizeof(WINE_MIDI) + (cIDs ? (cIDs-1) : 0) * sizeof(MIDIOPENSTRMID);
918
919 lpwm = (LPWINE_MIDI)MMDRV_Alloc(size, MMDRV_MIDIOUT, &hMidiOut, lpdwFlags,
920 lpdwCallback, lpdwInstance);
921
922 *lphMidiOut = hMidiOut;
923
924 if (lpwm) {
925 lpwm->mod.hMidi = hMidiOut;
926 lpwm->mod.dwCallback = *lpdwCallback;
927 lpwm->mod.dwInstance = *lpdwInstance;
928 lpwm->mod.dnDevNode = 0;
929 lpwm->mod.cIds = cIDs;
930 if (cIDs)
931 memcpy(&(lpwm->mod.rgIds), lpIDs, cIDs * sizeof(MIDIOPENSTRMID));
932 }
933 return lpwm;
934}
935
936/**************************************************************************
937 * midiOutOpen [WINMM.@]
938 */
940 DWORD_PTR dwCallback, DWORD_PTR dwInstance, DWORD dwFlags)
941{
942 HMIDIOUT hMidiOut;
943 LPWINE_MIDI lpwm;
944 UINT dwRet;
945
946 TRACE("(%p, %d, %08lX, %08lX, %08X);\n",
947 lphMidiOut, uDeviceID, dwCallback, dwInstance, dwFlags);
948
949 if (lphMidiOut != NULL) *lphMidiOut = 0;
950
951 dwRet = WINMM_CheckCallback(dwCallback, dwFlags, FALSE);
952 if (dwRet != MMSYSERR_NOERROR)
953 return dwRet;
954
955 lpwm = MIDI_OutAlloc(&hMidiOut, &dwCallback, &dwInstance, &dwFlags, 0, NULL);
956
957 if (lpwm == NULL)
958 return MMSYSERR_NOMEM;
959
960 lpwm->mld.uDeviceID = uDeviceID;
961
962 dwRet = MMDRV_Open((LPWINE_MLD)lpwm, MODM_OPEN, (DWORD_PTR)&lpwm->mod, dwFlags);
963
964 if (dwRet != MMSYSERR_NOERROR) {
965 MMDRV_Free(hMidiOut, (LPWINE_MLD)lpwm);
966 hMidiOut = 0;
967 }
968
969 if (lphMidiOut) *lphMidiOut = hMidiOut;
970 TRACE("=> %d hMidi=%p\n", dwRet, hMidiOut);
971
972 return dwRet;
973}
974
975/**************************************************************************
976 * midiOutClose [WINMM.@]
977 */
978UINT WINAPI midiOutClose(HMIDIOUT hMidiOut)
979{
980 LPWINE_MLD wmld;
981 DWORD dwRet;
982
983 TRACE("(%p)\n", hMidiOut);
984
985 if ((wmld = MMDRV_Get(hMidiOut, MMDRV_MIDIOUT, FALSE)) == NULL)
987
988 dwRet = MMDRV_Close(wmld, MODM_CLOSE);
989 MMDRV_Free(hMidiOut, wmld);
990
991 return dwRet;
992}
993
994/**************************************************************************
995 * midiOutPrepareHeader [WINMM.@]
996 */
998 MIDIHDR* lpMidiOutHdr, UINT uSize)
999{
1000 LPWINE_MLD wmld;
1001
1002 TRACE("(%p, %p, %d)\n", hMidiOut, lpMidiOutHdr, uSize);
1003
1004 if (lpMidiOutHdr == NULL || uSize < sizeof (MIDIHDR))
1005 return MMSYSERR_INVALPARAM;
1006
1007 if ((wmld = MMDRV_Get(hMidiOut, MMDRV_MIDIOUT, FALSE)) == NULL)
1008 return MMSYSERR_INVALHANDLE;
1009
1010 return MMDRV_Message(wmld, MODM_PREPARE, (DWORD_PTR)lpMidiOutHdr, uSize);
1011}
1012
1013/**************************************************************************
1014 * midiOutUnprepareHeader [WINMM.@]
1015 */
1017 MIDIHDR* lpMidiOutHdr, UINT uSize)
1018{
1019 LPWINE_MLD wmld;
1020
1021 TRACE("(%p, %p, %d)\n", hMidiOut, lpMidiOutHdr, uSize);
1022
1023 if (lpMidiOutHdr == NULL || uSize < sizeof (MIDIHDR))
1024 return MMSYSERR_INVALPARAM;
1025
1026 if (!(lpMidiOutHdr->dwFlags & MHDR_PREPARED)) {
1027 return MMSYSERR_NOERROR;
1028 }
1029
1030 if ((wmld = MMDRV_Get(hMidiOut, MMDRV_MIDIOUT, FALSE)) == NULL)
1031 return MMSYSERR_INVALHANDLE;
1032
1033 return MMDRV_Message(wmld, MODM_UNPREPARE, (DWORD_PTR)lpMidiOutHdr, uSize);
1034}
1035
1036/**************************************************************************
1037 * midiOutShortMsg [WINMM.@]
1038 */
1039UINT WINAPI midiOutShortMsg(HMIDIOUT hMidiOut, DWORD dwMsg)
1040{
1041 LPWINE_MLD wmld;
1042
1043 TRACE("(%p, %08X)\n", hMidiOut, dwMsg);
1044
1045 if ((wmld = MMDRV_Get(hMidiOut, MMDRV_MIDIOUT, FALSE)) == NULL)
1046 return MMSYSERR_INVALHANDLE;
1047
1048 return MMDRV_Message(wmld, MODM_DATA, dwMsg, 0L);
1049}
1050
1051/**************************************************************************
1052 * midiOutLongMsg [WINMM.@]
1053 */
1054UINT WINAPI midiOutLongMsg(HMIDIOUT hMidiOut,
1055 MIDIHDR* lpMidiOutHdr, UINT uSize)
1056{
1057 LPWINE_MLD wmld;
1058
1059 TRACE("(%p, %p, %d)\n", hMidiOut, lpMidiOutHdr, uSize);
1060
1061 if ((wmld = MMDRV_Get(hMidiOut, MMDRV_MIDIOUT, FALSE)) == NULL)
1062 return MMSYSERR_INVALHANDLE;
1063
1064 return MMDRV_Message(wmld, MODM_LONGDATA, (DWORD_PTR)lpMidiOutHdr, uSize);
1065}
1066
1067/**************************************************************************
1068 * midiOutReset [WINMM.@]
1069 */
1070UINT WINAPI midiOutReset(HMIDIOUT hMidiOut)
1071{
1072 LPWINE_MLD wmld;
1073
1074 TRACE("(%p)\n", hMidiOut);
1075
1076 if ((wmld = MMDRV_Get(hMidiOut, MMDRV_MIDIOUT, FALSE)) == NULL)
1077 return MMSYSERR_INVALHANDLE;
1078
1079 return MMDRV_Message(wmld, MODM_RESET, 0L, 0L);
1080}
1081
1082/**************************************************************************
1083 * midiOutGetVolume [WINMM.@]
1084 */
1085UINT WINAPI midiOutGetVolume(HMIDIOUT hMidiOut, DWORD* lpdwVolume)
1086{
1087 LPWINE_MLD wmld;
1088
1089 TRACE("(%p, %p);\n", hMidiOut, lpdwVolume);
1090
1091 if ((wmld = MMDRV_Get(hMidiOut, MMDRV_MIDIOUT, TRUE)) == NULL)
1092 return MMSYSERR_INVALHANDLE;
1093
1094 return MMDRV_Message(wmld, MODM_GETVOLUME, (DWORD_PTR)lpdwVolume, 0L);
1095}
1096
1097/**************************************************************************
1098 * midiOutSetVolume [WINMM.@]
1099 */
1100UINT WINAPI midiOutSetVolume(HMIDIOUT hMidiOut, DWORD dwVolume)
1101{
1102 LPWINE_MLD wmld;
1103
1104 TRACE("(%p, %d);\n", hMidiOut, dwVolume);
1105
1106 if ((wmld = MMDRV_Get(hMidiOut, MMDRV_MIDIOUT, TRUE)) == NULL)
1107 return MMSYSERR_INVALHANDLE;
1108
1109 return MMDRV_Message(wmld, MODM_SETVOLUME, dwVolume, 0L);
1110}
1111
1112/**************************************************************************
1113 * midiOutCachePatches [WINMM.@]
1114 */
1115UINT WINAPI midiOutCachePatches(HMIDIOUT hMidiOut, UINT uBank,
1116 WORD* lpwPatchArray, UINT uFlags)
1117{
1118 /* not really necessary to support this */
1119 FIXME("not supported yet\n");
1120 return MMSYSERR_NOTSUPPORTED;
1121}
1122
1123/**************************************************************************
1124 * midiOutCacheDrumPatches [WINMM.@]
1125 */
1126UINT WINAPI midiOutCacheDrumPatches(HMIDIOUT hMidiOut, UINT uPatch,
1127 WORD* lpwKeyArray, UINT uFlags)
1128{
1129 FIXME("not supported yet\n");
1130 return MMSYSERR_NOTSUPPORTED;
1131}
1132
1133/**************************************************************************
1134 * midiOutGetID [WINMM.@]
1135 */
1136UINT WINAPI midiOutGetID(HMIDIOUT hMidiOut, UINT* lpuDeviceID)
1137{
1138 LPWINE_MLD wmld;
1139
1140 TRACE("(%p, %p)\n", hMidiOut, lpuDeviceID);
1141
1142 if (lpuDeviceID == NULL) return MMSYSERR_INVALPARAM;
1143 if ((wmld = MMDRV_Get(hMidiOut, MMDRV_MIDIOUT, FALSE)) == NULL)
1144 return MMSYSERR_INVALHANDLE;
1145
1146 *lpuDeviceID = wmld->uDeviceID;
1147 return MMSYSERR_NOERROR;
1148}
1149
1150/**************************************************************************
1151 * midiOutMessage [WINMM.@]
1152 */
1153UINT WINAPI midiOutMessage(HMIDIOUT hMidiOut, UINT uMessage,
1154 DWORD_PTR dwParam1, DWORD_PTR dwParam2)
1155{
1156 LPWINE_MLD wmld;
1157
1158 TRACE("(%p, %04X, %08lX, %08lX)\n", hMidiOut, uMessage, dwParam1, dwParam2);
1159
1160 if ((wmld = MMDRV_Get(hMidiOut, MMDRV_MIDIOUT, FALSE)) == NULL) {
1161 /* HACK... */
1162 if (uMessage == 0x0001) {
1163 *(LPDWORD)dwParam1 = 1;
1164 return 0;
1165 }
1166 if ((wmld = MMDRV_Get(hMidiOut, MMDRV_MIDIOUT, TRUE)) != NULL) {
1167 return MMDRV_PhysicalFeatures(wmld, uMessage, dwParam1, dwParam2);
1168 }
1169 return MMSYSERR_INVALHANDLE;
1170 }
1171
1172 switch (uMessage) {
1173 case MODM_OPEN:
1174 case MODM_CLOSE:
1175 FIXME("can't handle OPEN or CLOSE message!\n");
1176 return MMSYSERR_NOTSUPPORTED;
1177 }
1178 return MMDRV_Message(wmld, uMessage, dwParam1, dwParam2);
1179}
1180
1181/**************************************************************************
1182 * midiInGetNumDevs [WINMM.@]
1183 */
1185{
1186 return MMDRV_GetNum(MMDRV_MIDIIN);
1187}
1188
1189/**************************************************************************
1190 * midiInGetDevCapsW [WINMM.@]
1191 */
1193{
1194 LPWINE_MLD wmld;
1195
1196 TRACE("(%ld, %p, %d);\n", uDeviceID, lpCaps, uSize);
1197
1198 if (lpCaps == NULL) return MMSYSERR_INVALPARAM;
1199
1200 if ((wmld = MMDRV_Get((HANDLE)uDeviceID, MMDRV_MIDIIN, TRUE)) == NULL)
1201 return MMSYSERR_INVALHANDLE;
1202
1203 return MMDRV_Message(wmld, MIDM_GETDEVCAPS, (DWORD_PTR)lpCaps, uSize);
1204}
1205
1206/**************************************************************************
1207 * midiInGetDevCapsA [WINMM.@]
1208 */
1210{
1211 MIDIINCAPSW micW;
1212 UINT ret;
1213
1214 if (lpCaps == NULL) return MMSYSERR_INVALPARAM;
1215
1216 ret = midiInGetDevCapsW(uDeviceID, &micW, sizeof(micW));
1217
1218 if (ret == MMSYSERR_NOERROR) {
1219 MIDIINCAPSA micA;
1220 micA.wMid = micW.wMid;
1221 micA.wPid = micW.wPid;
1222 micA.vDriverVersion = micW.vDriverVersion;
1223 WideCharToMultiByte( CP_ACP, 0, micW.szPname, -1, micA.szPname,
1224 sizeof(micA.szPname), NULL, NULL );
1225 micA.dwSupport = micW.dwSupport;
1226 memcpy(lpCaps, &micA, min(uSize, sizeof(micA)));
1227 }
1228 return ret;
1229}
1230
1231/**************************************************************************
1232 * midiInOpen [WINMM.@]
1233 */
1234MMRESULT WINAPI midiInOpen(HMIDIIN* lphMidiIn, UINT uDeviceID,
1235 DWORD_PTR dwCallback, DWORD_PTR dwInstance, DWORD dwFlags)
1236{
1237 HANDLE hMidiIn;
1238 LPWINE_MIDI lpwm;
1239 DWORD dwRet;
1240
1241 TRACE("(%p, %d, %08lX, %08lX, %08X);\n",
1242 lphMidiIn, uDeviceID, dwCallback, dwInstance, dwFlags);
1243
1244 if (lphMidiIn != NULL) *lphMidiIn = 0;
1245
1246 dwRet = WINMM_CheckCallback(dwCallback, dwFlags, FALSE);
1247 if (dwRet != MMSYSERR_NOERROR)
1248 return dwRet;
1249
1250 lpwm = (LPWINE_MIDI)MMDRV_Alloc(sizeof(WINE_MIDI), MMDRV_MIDIIN, &hMidiIn,
1251 &dwFlags, &dwCallback, &dwInstance);
1252
1253 if (lpwm == NULL)
1254 return MMSYSERR_NOMEM;
1255
1256 lpwm->mod.hMidi = hMidiIn;
1257 lpwm->mod.dwCallback = dwCallback;
1258 lpwm->mod.dwInstance = dwInstance;
1259
1260 lpwm->mld.uDeviceID = uDeviceID;
1261 dwRet = MMDRV_Open(&lpwm->mld, MIDM_OPEN, (DWORD_PTR)&lpwm->mod, dwFlags);
1262
1263 if (dwRet != MMSYSERR_NOERROR) {
1264 MMDRV_Free(hMidiIn, &lpwm->mld);
1265 hMidiIn = 0;
1266 }
1267 if (lphMidiIn != NULL) *lphMidiIn = hMidiIn;
1268 TRACE("=> %d hMidi=%p\n", dwRet, hMidiIn);
1269
1270 return dwRet;
1271}
1272
1273/**************************************************************************
1274 * midiInClose [WINMM.@]
1275 */
1276UINT WINAPI midiInClose(HMIDIIN hMidiIn)
1277{
1278 LPWINE_MLD wmld;
1279 DWORD dwRet;
1280
1281 TRACE("(%p)\n", hMidiIn);
1282
1283 if ((wmld = MMDRV_Get(hMidiIn, MMDRV_MIDIIN, FALSE)) == NULL)
1284 return MMSYSERR_INVALHANDLE;
1285
1286 dwRet = MMDRV_Close(wmld, MIDM_CLOSE);
1287 MMDRV_Free(hMidiIn, wmld);
1288 return dwRet;
1289}
1290
1291/**************************************************************************
1292 * midiInPrepareHeader [WINMM.@]
1293 */
1295 MIDIHDR* lpMidiInHdr, UINT uSize)
1296{
1297 LPWINE_MLD wmld;
1298
1299 TRACE("(%p, %p, %d)\n", hMidiIn, lpMidiInHdr, uSize);
1300
1301 if (lpMidiInHdr == NULL || uSize < sizeof (MIDIHDR))
1302 return MMSYSERR_INVALPARAM;
1303
1304 if ((wmld = MMDRV_Get(hMidiIn, MMDRV_MIDIIN, FALSE)) == NULL)
1305 return MMSYSERR_INVALHANDLE;
1306
1307 return MMDRV_Message(wmld, MIDM_PREPARE, (DWORD_PTR)lpMidiInHdr, uSize);
1308}
1309
1310/**************************************************************************
1311 * midiInUnprepareHeader [WINMM.@]
1312 */
1314 MIDIHDR* lpMidiInHdr, UINT uSize)
1315{
1316 LPWINE_MLD wmld;
1317
1318 TRACE("(%p, %p, %d)\n", hMidiIn, lpMidiInHdr, uSize);
1319
1320 if (lpMidiInHdr == NULL || uSize < sizeof (MIDIHDR))
1321 return MMSYSERR_INVALPARAM;
1322
1323 if (!(lpMidiInHdr->dwFlags & MHDR_PREPARED)) {
1324 return MMSYSERR_NOERROR;
1325 }
1326
1327 if ((wmld = MMDRV_Get(hMidiIn, MMDRV_MIDIIN, FALSE)) == NULL)
1328 return MMSYSERR_INVALHANDLE;
1329
1330 return MMDRV_Message(wmld, MIDM_UNPREPARE, (DWORD_PTR)lpMidiInHdr, uSize);
1331}
1332
1333/**************************************************************************
1334 * midiInAddBuffer [WINMM.@]
1335 */
1337 MIDIHDR* lpMidiInHdr, UINT uSize)
1338{
1339 LPWINE_MLD wmld;
1340
1341 TRACE("(%p, %p, %d)\n", hMidiIn, lpMidiInHdr, uSize);
1342
1343 if ((wmld = MMDRV_Get(hMidiIn, MMDRV_MIDIIN, FALSE)) == NULL)
1344 return MMSYSERR_INVALHANDLE;
1345
1346 return MMDRV_Message(wmld, MIDM_ADDBUFFER, (DWORD_PTR)lpMidiInHdr, uSize);
1347}
1348
1349/**************************************************************************
1350 * midiInStart [WINMM.@]
1351 */
1352UINT WINAPI midiInStart(HMIDIIN hMidiIn)
1353{
1354 LPWINE_MLD wmld;
1355
1356 TRACE("(%p)\n", hMidiIn);
1357
1358 if ((wmld = MMDRV_Get(hMidiIn, MMDRV_MIDIIN, FALSE)) == NULL)
1359 return MMSYSERR_INVALHANDLE;
1360
1361 return MMDRV_Message(wmld, MIDM_START, 0L, 0L);
1362}
1363
1364/**************************************************************************
1365 * midiInStop [WINMM.@]
1366 */
1367UINT WINAPI midiInStop(HMIDIIN hMidiIn)
1368{
1369 LPWINE_MLD wmld;
1370
1371 TRACE("(%p)\n", hMidiIn);
1372
1373 if ((wmld = MMDRV_Get(hMidiIn, MMDRV_MIDIIN, FALSE)) == NULL)
1374 return MMSYSERR_INVALHANDLE;
1375
1376 return MMDRV_Message(wmld, MIDM_STOP, 0L, 0L);
1377}
1378
1379/**************************************************************************
1380 * midiInReset [WINMM.@]
1381 */
1382UINT WINAPI midiInReset(HMIDIIN hMidiIn)
1383{
1384 LPWINE_MLD wmld;
1385
1386 TRACE("(%p)\n", hMidiIn);
1387
1388 if ((wmld = MMDRV_Get(hMidiIn, MMDRV_MIDIIN, FALSE)) == NULL)
1389 return MMSYSERR_INVALHANDLE;
1390
1391 return MMDRV_Message(wmld, MIDM_RESET, 0L, 0L);
1392}
1393
1394/**************************************************************************
1395 * midiInGetID [WINMM.@]
1396 */
1397UINT WINAPI midiInGetID(HMIDIIN hMidiIn, UINT* lpuDeviceID)
1398{
1399 LPWINE_MLD wmld;
1400
1401 TRACE("(%p, %p)\n", hMidiIn, lpuDeviceID);
1402
1403 if (lpuDeviceID == NULL) return MMSYSERR_INVALPARAM;
1404
1405 if ((wmld = MMDRV_Get(hMidiIn, MMDRV_MIDIIN, TRUE)) == NULL)
1406 return MMSYSERR_INVALHANDLE;
1407
1408 *lpuDeviceID = wmld->uDeviceID;
1409
1410 return MMSYSERR_NOERROR;
1411}
1412
1413/**************************************************************************
1414 * midiInMessage [WINMM.@]
1415 */
1416UINT WINAPI midiInMessage(HMIDIIN hMidiIn, UINT uMessage,
1417 DWORD_PTR dwParam1, DWORD_PTR dwParam2)
1418{
1419 LPWINE_MLD wmld;
1420
1421 TRACE("(%p, %04X, %08lX, %08lX)\n", hMidiIn, uMessage, dwParam1, dwParam2);
1422
1423 if ((wmld = MMDRV_Get(hMidiIn, MMDRV_MIDIIN, FALSE)) == NULL)
1424 return MMSYSERR_INVALHANDLE;
1425
1426 switch (uMessage) {
1427 case MIDM_OPEN:
1428 case MIDM_CLOSE:
1429 FIXME("can't handle OPEN or CLOSE message!\n");
1430 return MMSYSERR_NOTSUPPORTED;
1431 }
1432 return MMDRV_Message(wmld, uMessage, dwParam1, dwParam2);
1433}
1434
1435/**************************************************************************
1436 * midiConnect [WINMM.@]
1437 */
1438MMRESULT WINAPI midiConnect(HMIDI hMidi, HMIDIOUT hmo, LPVOID pReserved)
1439{
1440 FIXME("(%p, %p, %p): Stub\n", hMidi, hmo, pReserved);
1441 return MMSYSERR_ERROR;
1442}
1443
1444/**************************************************************************
1445 * midiDisconnect [WINMM.@]
1446 */
1447MMRESULT WINAPI midiDisconnect(HMIDI hMidi, HMIDIOUT hmo, LPVOID pReserved)
1448{
1449 FIXME("(%p, %p, %p): Stub\n", hMidi, hmo, pReserved);
1450 return MMSYSERR_ERROR;
1451}
1452
1453typedef struct WINE_MIDIStream {
1454 HMIDIOUT hDevice;
1466
1467#define WINE_MSM_HEADER (WM_USER+0)
1468#define WINE_MSM_STOP (WM_USER+1)
1469
1470/**************************************************************************
1471 * MMSYSTEM_GetMidiStream [internal]
1472 */
1473static BOOL MMSYSTEM_GetMidiStream(HMIDISTRM hMidiStrm, WINE_MIDIStream** lpMidiStrm, WINE_MIDI** lplpwm)
1474{
1475 WINE_MIDI* lpwm = (LPWINE_MIDI)MMDRV_Get(hMidiStrm, MMDRV_MIDIOUT, FALSE);
1476
1477 if (lplpwm)
1478 *lplpwm = lpwm;
1479
1480 if (lpwm == NULL) {
1481 return FALSE;
1482 }
1483
1484 *lpMidiStrm = (WINE_MIDIStream*)(ULONG_PTR)lpwm->mod.rgIds.dwStreamID; // FIXME: not 64 bit safe
1485
1486 return *lpMidiStrm != NULL;
1487}
1488
1489/**************************************************************************
1490 * MMSYSTEM_MidiStream_Convert [internal]
1491 */
1493{
1494 DWORD ret = 0;
1495
1496 if (lpMidiStrm->dwTimeDiv == 0) {
1497 FIXME("Shouldn't happen. lpMidiStrm->dwTimeDiv = 0\n");
1498 } else if (lpMidiStrm->dwTimeDiv > 0x8000) { /* SMPTE, unchecked FIXME? */
1499 int nf = -(char)HIBYTE(lpMidiStrm->dwTimeDiv); /* number of frames */
1500 int nsf = LOBYTE(lpMidiStrm->dwTimeDiv); /* number of sub-frames */
1501 ret = (pulse * 1000) / (nf * nsf);
1502 } else {
1503 ret = (DWORD)((double)pulse * ((double)lpMidiStrm->dwTempo / 1000) /
1504 (double)lpMidiStrm->dwTimeDiv);
1505 }
1506
1507 return ret;
1508}
1509
1510/**************************************************************************
1511 * MMSYSTEM_MidiStream_MessageHandler [internal]
1512 */
1514{
1515 LPMIDIHDR lpMidiHdr;
1516 LPMIDIHDR* lpmh;
1517 LPBYTE lpData;
1518
1519 switch (msg->message) {
1520 case WM_QUIT:
1521 SetEvent(lpMidiStrm->hEvent);
1522 return FALSE;
1523 case WINE_MSM_STOP:
1524 TRACE("STOP\n");
1525 /* this is not quite what MS doc says... */
1526 midiOutReset(lpMidiStrm->hDevice);
1527 /* empty list of already submitted buffers */
1528 for (lpMidiHdr = lpMidiStrm->lpMidiHdr; lpMidiHdr; lpMidiHdr = lpMidiHdr->lpNext) {
1529 lpMidiHdr->dwFlags |= MHDR_DONE;
1530 lpMidiHdr->dwFlags &= ~MHDR_INQUEUE;
1531
1532 DriverCallback(lpwm->mod.dwCallback, lpMidiStrm->wFlags,
1533 (HDRVR)lpMidiStrm->hDevice, MM_MOM_DONE,
1534 lpwm->mod.dwInstance, (DWORD_PTR)lpMidiHdr, 0);
1535 }
1536 lpMidiStrm->lpMidiHdr = 0;
1537 SetEvent(lpMidiStrm->hEvent);
1538 break;
1539 case WINE_MSM_HEADER:
1540 /* sets initial tick count for first MIDIHDR */
1541 if (!lpMidiStrm->dwStartTicks)
1542 lpMidiStrm->dwStartTicks = GetTickCount();
1543
1544 /* FIXME(EPP): "I don't understand the content of the first MIDIHDR sent
1545 * by native mcimidi, it doesn't look like a correct one".
1546 * this trick allows to throw it away... but I don't like it.
1547 * It looks like part of the file I'm trying to play and definitively looks
1548 * like raw midi content
1549 * I'd really like to understand why native mcimidi sends it. Perhaps a bad
1550 * synchronization issue where native mcimidi is still processing raw MIDI
1551 * content before generating MIDIEVENTs ?
1552 *
1553 * 4c 04 89 3b 00 81 7c 99 3b 43 00 99 23 5e 04 89 L..;..|.;C..#^..
1554 * 3b 00 00 89 23 00 7c 99 3b 45 00 99 28 62 04 89 ;...#.|.;E..(b..
1555 * 3b 00 00 89 28 00 81 7c 99 3b 4e 00 99 23 5e 04 ;...(..|.;N..#^.
1556 * 89 3b 00 00 89 23 00 7c 99 3b 45 00 99 23 78 04 .;...#.|.;E..#x.
1557 * 89 3b 00 00 89 23 00 81 7c 99 3b 48 00 99 23 5e .;...#..|.;H..#^
1558 * 04 89 3b 00 00 89 23 00 7c 99 3b 4e 00 99 28 62 ..;...#.|.;N..(b
1559 * 04 89 3b 00 00 89 28 00 81 7c 99 39 4c 00 99 23 ..;...(..|.9L..#
1560 * 5e 04 89 39 00 00 89 23 00 82 7c 99 3b 4c 00 99 ^..9...#..|.;L..
1561 * 23 5e 04 89 3b 00 00 89 23 00 7c 99 3b 48 00 99 #^..;...#.|.;H..
1562 * 28 62 04 89 3b 00 00 89 28 00 81 7c 99 3b 3f 04 (b..;...(..|.;?.
1563 * 89 3b 00 1c 99 23 5e 04 89 23 00 5c 99 3b 45 00 .;...#^..#.\.;E.
1564 * 99 23 78 04 89 3b 00 00 89 23 00 81 7c 99 3b 46 .#x..;...#..|.;F
1565 * 00 99 23 5e 04 89 3b 00 00 89 23 00 7c 99 3b 48 ..#^..;...#.|.;H
1566 * 00 99 28 62 04 89 3b 00 00 89 28 00 81 7c 99 3b ..(b..;...(..|.;
1567 * 46 00 99 23 5e 04 89 3b 00 00 89 23 00 7c 99 3b F..#^..;...#.|.;
1568 * 48 00 99 23 78 04 89 3b 00 00 89 23 00 81 7c 99 H..#x..;...#..|.
1569 * 3b 4c 00 99 23 5e 04 89 3b 00 00 89 23 00 7c 99 ;L..#^..;...#.|.
1570 */
1571 lpMidiHdr = (LPMIDIHDR)msg->lParam;
1572 lpData = (LPBYTE)lpMidiHdr->lpData;
1573 TRACE("Adding %s lpMidiHdr=%p [lpData=0x%p dwBufferLength=%u/%u dwFlags=0x%08x size=%lu]\n",
1574 (lpMidiHdr->dwFlags & MHDR_ISSTRM) ? "stream" : "regular", lpMidiHdr,
1575 lpMidiHdr, lpMidiHdr->dwBufferLength, lpMidiHdr->dwBytesRecorded,
1576 lpMidiHdr->dwFlags, msg->wParam);
1577#if 0
1578 /* dumps content of lpMidiHdr->lpData
1579 * FIXME: there should be a debug routine somewhere that already does this
1580 * I hate spreading this type of shit all around the code
1581 */
1582 for (dwToGo = 0; dwToGo < lpMidiHdr->dwBufferLength; dwToGo += 16) {
1583 DWORD i;
1584 BYTE ch;
1585
1586 for (i = 0; i < min(16, lpMidiHdr->dwBufferLength - dwToGo); i++)
1587 printf("%02x ", lpData[dwToGo + i]);
1588 for (; i < 16; i++)
1589 printf(" ");
1590 for (i = 0; i < min(16, lpMidiHdr->dwBufferLength - dwToGo); i++) {
1591 ch = lpData[dwToGo + i];
1592 printf("%c", (ch >= 0x20 && ch <= 0x7F) ? ch : '.');
1593 }
1594 printf("\n");
1595 }
1596#endif
1597 if (((LPMIDIEVENT)lpData)->dwStreamID != 0 &&
1598 ((LPMIDIEVENT)lpData)->dwStreamID != 0xFFFFFFFF &&
1599 /* FIXME: not 64 bit safe */
1600 ((LPMIDIEVENT)lpData)->dwStreamID != (DWORD_PTR)lpMidiStrm) {
1601 FIXME("Dropping bad %s lpMidiHdr (streamID=%08x)\n",
1602 (lpMidiHdr->dwFlags & MHDR_ISSTRM) ? "stream" : "regular",
1603 ((LPMIDIEVENT)lpData)->dwStreamID);
1604 lpMidiHdr->dwFlags |= MHDR_DONE;
1605 lpMidiHdr->dwFlags &= ~MHDR_INQUEUE;
1606
1607 DriverCallback(lpwm->mod.dwCallback, lpMidiStrm->wFlags,
1608 (HDRVR)lpMidiStrm->hDevice, MM_MOM_DONE,
1609 lpwm->mod.dwInstance, (DWORD_PTR)lpMidiHdr, 0);
1610 break;
1611 }
1612
1613 for (lpmh = &lpMidiStrm->lpMidiHdr; *lpmh; lpmh = &(*lpmh)->lpNext);
1614 *lpmh = lpMidiHdr;
1615 lpMidiHdr = (LPMIDIHDR)msg->lParam;
1616 lpMidiHdr->lpNext = 0;
1617 lpMidiHdr->dwFlags |= MHDR_INQUEUE;
1618 lpMidiHdr->dwFlags &= ~MHDR_DONE;
1619 lpMidiHdr->dwOffset = 0;
1620
1621 break;
1622 default:
1623 FIXME("Unknown message %d\n", msg->message);
1624 break;
1625 }
1626 return TRUE;
1627}
1628
1629/**************************************************************************
1630 * MMSYSTEM_MidiStream_Player [internal]
1631 */
1633{
1634 WINE_MIDIStream* lpMidiStrm = pmt;
1635 WINE_MIDI* lpwm;
1636 MSG msg;
1637 DWORD dwToGo;
1638 DWORD dwCurrTC;
1639 LPMIDIHDR lpMidiHdr;
1640 LPMIDIEVENT me;
1641 LPBYTE lpData = 0;
1642
1643 TRACE("(%p)!\n", lpMidiStrm);
1644
1645 if (!lpMidiStrm ||
1646 (lpwm = (LPWINE_MIDI)MMDRV_Get(lpMidiStrm->hDevice, MMDRV_MIDIOUT, FALSE)) == NULL)
1647 goto the_end;
1648
1649 /* force thread's queue creation */
1650 /* Used to be InitThreadInput16(0, 5); */
1651 /* but following works also with hack in midiStreamOpen */
1652 PeekMessageA(&msg, 0, 0, 0, 0);
1653
1654 /* FIXME: this next line must be called before midiStreamOut or midiStreamRestart are called */
1655 SetEvent(lpMidiStrm->hEvent);
1656 TRACE("Ready to go 1\n");
1657 /* thread is started in paused mode */
1658 SuspendThread(lpMidiStrm->hThread);
1659 TRACE("Ready to go 2\n");
1660
1661 lpMidiStrm->dwStartTicks = 0;
1662 lpMidiStrm->dwPulses = 0;
1663
1664 lpMidiStrm->lpMidiHdr = 0;
1665
1666 for (;;) {
1667 lpMidiHdr = lpMidiStrm->lpMidiHdr;
1668 if (!lpMidiHdr) {
1669 /* for first message, block until one arrives, then process all that are available */
1670 GetMessageA(&msg, 0, 0, 0);
1671 do {
1672 if (!MMSYSTEM_MidiStream_MessageHandler(lpMidiStrm, lpwm, &msg))
1673 goto the_end;
1674 } while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE));
1675 lpData = 0;
1676 continue;
1677 }
1678
1679 if (!lpData)
1680 lpData = (LPBYTE)lpMidiHdr->lpData;
1681
1682 me = (LPMIDIEVENT)(lpData + lpMidiHdr->dwOffset);
1683
1684 /* do we have to wait ? */
1685 if (me->dwDeltaTime) {
1686 lpMidiStrm->dwPositionMS += MMSYSTEM_MidiStream_Convert(lpMidiStrm, me->dwDeltaTime);
1687 lpMidiStrm->dwPulses += me->dwDeltaTime;
1688
1689 dwToGo = lpMidiStrm->dwStartTicks + lpMidiStrm->dwPositionMS;
1690
1691 TRACE("%d/%d/%d\n", dwToGo, GetTickCount(), me->dwDeltaTime);
1692 while ((dwCurrTC = GetTickCount()) < dwToGo) {
1693 if (MsgWaitForMultipleObjects(0, NULL, FALSE, dwToGo - dwCurrTC, QS_ALLINPUT) == WAIT_OBJECT_0) {
1694 /* got a message, handle it */
1695 while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE)) {
1696 if (!MMSYSTEM_MidiStream_MessageHandler(lpMidiStrm, lpwm, &msg))
1697 goto the_end;
1698 }
1699 lpData = 0;
1700 } else {
1701 /* timeout, so me->dwDeltaTime is elapsed, can break the while loop */
1702 break;
1703 }
1704 }
1705 }
1706 switch (MEVT_EVENTTYPE(me->dwEvent & ~MEVT_F_CALLBACK)) {
1707 case MEVT_COMMENT:
1708 FIXME("NIY: MEVT_COMMENT\n");
1709 /* do nothing, skip bytes */
1710 break;
1711 case MEVT_LONGMSG:
1712 FIXME("NIY: MEVT_LONGMSG, aka sending Sysex event\n");
1713 break;
1714 case MEVT_NOP:
1715 break;
1716 case MEVT_SHORTMSG:
1717 midiOutShortMsg(lpMidiStrm->hDevice, MEVT_EVENTPARM(me->dwEvent));
1718 break;
1719 case MEVT_TEMPO:
1720 lpMidiStrm->dwTempo = MEVT_EVENTPARM(me->dwEvent);
1721 break;
1722 case MEVT_VERSION:
1723 break;
1724 default:
1725 FIXME("Unknown MEVT (0x%02x)\n", MEVT_EVENTTYPE(me->dwEvent & ~MEVT_F_CALLBACK));
1726 break;
1727 }
1728 if (me->dwEvent & MEVT_F_CALLBACK) {
1729 DriverCallback(lpwm->mod.dwCallback, lpMidiStrm->wFlags,
1730 (HDRVR)lpMidiStrm->hDevice, MM_MOM_POSITIONCB,
1731 lpwm->mod.dwInstance, (LPARAM)lpMidiHdr, 0L);
1732 }
1733 lpMidiHdr->dwOffset += sizeof(MIDIEVENT) - sizeof(me->dwParms);
1734 if (me->dwEvent & MEVT_F_LONG)
1735 lpMidiHdr->dwOffset += (MEVT_EVENTPARM(me->dwEvent) + 3) & ~3;
1736 if (lpMidiHdr->dwOffset >= lpMidiHdr->dwBufferLength) {
1737 /* done with this header */
1738 lpMidiHdr->dwFlags |= MHDR_DONE;
1739 lpMidiHdr->dwFlags &= ~MHDR_INQUEUE;
1740
1741 lpMidiStrm->lpMidiHdr = lpMidiHdr->lpNext;
1742 DriverCallback(lpwm->mod.dwCallback, lpMidiStrm->wFlags,
1743 (HDRVR)lpMidiStrm->hDevice, MM_MOM_DONE,
1744 lpwm->mod.dwInstance, (DWORD_PTR)lpMidiHdr, 0);
1745 lpData = 0;
1746 }
1747 }
1748the_end:
1749 TRACE("End of thread\n");
1750 ExitThread(0);
1751 return 0; /* for removing the warning, never executed */
1752}
1753
1754/**************************************************************************
1755 * MMSYSTEM_MidiStream_PostMessage [internal]
1756 */
1758{
1759 if (PostThreadMessageA(lpMidiStrm->dwThreadID, msg, pmt1, pmt2)) {
1760 //DWORD count;
1761
1762 //ReleaseThunkLock(&count);
1763 WaitForSingleObject(lpMidiStrm->hEvent, INFINITE);
1764 //RestoreThunkLock(count);
1765 } else {
1766 WARN("bad PostThreadMessageA\n");
1767 return FALSE;
1768 }
1769 return TRUE;
1770}
1771
1772/**************************************************************************
1773 * midiStreamClose [WINMM.@]
1774 */
1775MMRESULT WINAPI midiStreamClose(HMIDISTRM hMidiStrm)
1776{
1777 WINE_MIDIStream* lpMidiStrm;
1778
1779 TRACE("(%p)!\n", hMidiStrm);
1780
1781 if (!MMSYSTEM_GetMidiStream(hMidiStrm, &lpMidiStrm, NULL))
1782 return MMSYSERR_INVALHANDLE;
1783
1784 midiStreamStop(hMidiStrm);
1785 MMSYSTEM_MidiStream_PostMessage(lpMidiStrm, WM_QUIT, 0, 0);
1786 HeapFree(GetProcessHeap(), 0, lpMidiStrm);
1787 CloseHandle(lpMidiStrm->hEvent);
1788
1789 return midiOutClose((HMIDIOUT)hMidiStrm);
1790}
1791
1792/**************************************************************************
1793 * midiStreamOpen [WINMM.@]
1794 */
1795MMRESULT WINAPI midiStreamOpen(HMIDISTRM* lphMidiStrm, LPUINT lpuDeviceID,
1796 DWORD cMidi, DWORD_PTR dwCallback,
1797 DWORD_PTR dwInstance, DWORD fdwOpen)
1798{
1799 WINE_MIDIStream* lpMidiStrm;
1800 MMRESULT ret;
1801 MIDIOPENSTRMID mosm;
1802 LPWINE_MIDI lpwm;
1803 HMIDIOUT hMidiOut;
1804
1805 TRACE("(%p, %p, %d, 0x%08lx, 0x%08lx, 0x%08x)!\n",
1806 lphMidiStrm, lpuDeviceID, cMidi, dwCallback, dwInstance, fdwOpen);
1807
1808 if (cMidi != 1 || lphMidiStrm == NULL || lpuDeviceID == NULL)
1809 return MMSYSERR_INVALPARAM;
1810
1811 ret = WINMM_CheckCallback(dwCallback, fdwOpen, FALSE);
1812 if (ret != MMSYSERR_NOERROR)
1813 return ret;
1814
1815 lpMidiStrm = HeapAlloc(GetProcessHeap(), 0, sizeof(WINE_MIDIStream));
1816 if (!lpMidiStrm)
1817 return MMSYSERR_NOMEM;
1818
1819 lpMidiStrm->dwTempo = 500000;
1820 lpMidiStrm->dwTimeDiv = 480; /* 480 is 120 quarter notes per minute *//* FIXME ??*/
1821 lpMidiStrm->dwPositionMS = 0;
1822
1823 mosm.dwStreamID = (DWORD_PTR)lpMidiStrm; // FIXME: not 64 bit safe
1824 /* FIXME: the correct value is not allocated yet for MAPPER */
1825 mosm.wDeviceID = *lpuDeviceID;
1826 lpwm = MIDI_OutAlloc(&hMidiOut, &dwCallback, &dwInstance, &fdwOpen, 1, &mosm);
1827 lpMidiStrm->hDevice = hMidiOut;
1828 *lphMidiStrm = (HMIDISTRM)hMidiOut;
1829
1830 lpwm->mld.uDeviceID = *lpuDeviceID;
1831
1832 ret = MMDRV_Open(&lpwm->mld, MODM_OPEN, (DWORD_PTR)&lpwm->mod, fdwOpen);
1833 lpMidiStrm->hEvent = CreateEventW(NULL, FALSE, FALSE, NULL);
1834 lpMidiStrm->wFlags = HIWORD(fdwOpen);
1835
1837 lpMidiStrm, 0, &(lpMidiStrm->dwThreadID));
1838
1839 if (!lpMidiStrm->hThread) {
1840 midiStreamClose((HMIDISTRM)hMidiOut);
1841 return MMSYSERR_NOMEM;
1842 }
1844
1845 /* wait for thread to have started, and for its queue to be created */
1846 {
1847 //DWORD count;
1848
1849 /* (Release|Restore)ThunkLock() is needed when this method is called from 16 bit code,
1850 * (meaning the Win16Lock is set), so that it's released and the 32 bit thread running
1851 * MMSYSTEM_MidiStreamPlayer can acquire Win16Lock to create its queue.
1852 */
1853 //ReleaseThunkLock(&count);
1854 WaitForSingleObject(lpMidiStrm->hEvent, INFINITE);
1855 //RestoreThunkLock(count);
1856 }
1857
1858 TRACE("=> (%u/%d) hMidi=%p ret=%d lpMidiStrm=%p\n",
1859 *lpuDeviceID, lpwm->mld.uDeviceID, *lphMidiStrm, ret, lpMidiStrm);
1860 return ret;
1861}
1862
1863/**************************************************************************
1864 * midiStreamOut [WINMM.@]
1865 */
1866MMRESULT WINAPI midiStreamOut(HMIDISTRM hMidiStrm, LPMIDIHDR lpMidiHdr,
1867 UINT cbMidiHdr)
1868{
1869 WINE_MIDIStream* lpMidiStrm;
1871
1872 TRACE("(%p, %p, %u)!\n", hMidiStrm, lpMidiHdr, cbMidiHdr);
1873
1874 if (cbMidiHdr < offsetof(MIDIHDR,dwOffset) || !lpMidiHdr || !lpMidiHdr->lpData
1875 || lpMidiHdr->dwBufferLength < lpMidiHdr->dwBytesRecorded
1876 || lpMidiHdr->dwBytesRecorded % 4 /* player expects DWORD padding */)
1877 return MMSYSERR_INVALPARAM;
1878 /* FIXME: Native additionally checks if the MIDIEVENTs in lpData
1879 * exactly fit dwBytesRecorded. */
1880
1881 if (!(lpMidiHdr->dwFlags & MHDR_PREPARED))
1882 return MIDIERR_UNPREPARED;
1883
1884 if (lpMidiHdr->dwFlags & MHDR_INQUEUE)
1885 return MIDIERR_STILLPLAYING;
1886
1887 if (!MMSYSTEM_GetMidiStream(hMidiStrm, &lpMidiStrm, NULL)) {
1889 } else {
1890 lpMidiHdr->dwFlags |= MHDR_ISSTRM;
1891 if (!PostThreadMessageA(lpMidiStrm->dwThreadID,
1892 WINE_MSM_HEADER, cbMidiHdr,
1893 (LPARAM)lpMidiHdr)) {
1894 WARN("bad PostThreadMessageA\n");
1896 }
1897 }
1898 return ret;
1899}
1900
1901/**************************************************************************
1902 * midiStreamPause [WINMM.@]
1903 */
1904MMRESULT WINAPI midiStreamPause(HMIDISTRM hMidiStrm)
1905{
1906 WINE_MIDIStream* lpMidiStrm;
1908
1909 TRACE("(%p)!\n", hMidiStrm);
1910
1911 if (!MMSYSTEM_GetMidiStream(hMidiStrm, &lpMidiStrm, NULL)) {
1913 } else {
1914 if (SuspendThread(lpMidiStrm->hThread) == 0xFFFFFFFF) {
1915 WARN("bad Suspend (%d)\n", GetLastError());
1917 }
1918 }
1919 return ret;
1920}
1921
1922/**************************************************************************
1923 * midiStreamPosition [WINMM.@]
1924 */
1925MMRESULT WINAPI midiStreamPosition(HMIDISTRM hMidiStrm, LPMMTIME lpMMT, UINT cbmmt)
1926{
1927 WINE_MIDIStream* lpMidiStrm;
1929
1930 TRACE("(%p, %p, %u)!\n", hMidiStrm, lpMMT, cbmmt);
1931
1932 if (!MMSYSTEM_GetMidiStream(hMidiStrm, &lpMidiStrm, NULL)) {
1934 } else if (lpMMT == NULL || cbmmt != sizeof(MMTIME)) {
1936 } else {
1937 switch (lpMMT->wType) {
1938 case TIME_MS:
1939 lpMMT->u.ms = lpMidiStrm->dwPositionMS;
1940 TRACE("=> %d ms\n", lpMMT->u.ms);
1941 break;
1942 case TIME_TICKS:
1943 lpMMT->u.ticks = lpMidiStrm->dwPulses;
1944 TRACE("=> %d ticks\n", lpMMT->u.ticks);
1945 break;
1946 default:
1947 WARN("Unsupported time type %d\n", lpMMT->wType);
1948 lpMMT->wType = TIME_MS;
1950 break;
1951 }
1952 }
1953 return ret;
1954}
1955
1956/**************************************************************************
1957 * midiStreamProperty [WINMM.@]
1958 */
1959MMRESULT WINAPI midiStreamProperty(HMIDISTRM hMidiStrm, LPBYTE lpPropData, DWORD dwProperty)
1960{
1961 WINE_MIDIStream* lpMidiStrm;
1963
1964 TRACE("(%p, %p, %x)\n", hMidiStrm, lpPropData, dwProperty);
1965
1966 if (!MMSYSTEM_GetMidiStream(hMidiStrm, &lpMidiStrm, NULL)) {
1968 } else if ((dwProperty & (MIDIPROP_GET|MIDIPROP_SET)) == 0) {
1970 } else if (dwProperty & MIDIPROP_TEMPO) {
1971 MIDIPROPTEMPO* mpt = (MIDIPROPTEMPO*)lpPropData;
1972
1973 if (sizeof(MIDIPROPTEMPO) != mpt->cbStruct) {
1975 } else if (dwProperty & MIDIPROP_SET) {
1976 lpMidiStrm->dwTempo = mpt->dwTempo;
1977 TRACE("Setting tempo to %d\n", mpt->dwTempo);
1978 } else if (dwProperty & MIDIPROP_GET) {
1979 mpt->dwTempo = lpMidiStrm->dwTempo;
1980 TRACE("Getting tempo <= %d\n", mpt->dwTempo);
1981 }
1982 } else if (dwProperty & MIDIPROP_TIMEDIV) {
1983 MIDIPROPTIMEDIV* mptd = (MIDIPROPTIMEDIV*)lpPropData;
1984
1985 if (sizeof(MIDIPROPTIMEDIV) != mptd->cbStruct) {
1987 } else if (dwProperty & MIDIPROP_SET) {
1988 lpMidiStrm->dwTimeDiv = mptd->dwTimeDiv;
1989 TRACE("Setting time div to %d\n", mptd->dwTimeDiv);
1990 } else if (dwProperty & MIDIPROP_GET) {
1991 mptd->dwTimeDiv = lpMidiStrm->dwTimeDiv;
1992 TRACE("Getting time div <= %d\n", mptd->dwTimeDiv);
1993 }
1994 } else {
1996 }
1997
1998 return ret;
1999}
2000
2001/**************************************************************************
2002 * midiStreamRestart [WINMM.@]
2003 */
2005{
2006 WINE_MIDIStream* lpMidiStrm;
2008
2009 TRACE("(%p)!\n", hMidiStrm);
2010
2011 if (!MMSYSTEM_GetMidiStream(hMidiStrm, &lpMidiStrm, NULL)) {
2013 } else {
2014 DWORD ret;
2015
2016 /* since we increase the thread suspend count on each midiStreamPause
2017 * there may be a need for several midiStreamResume
2018 */
2019 do {
2020 ret = ResumeThread(lpMidiStrm->hThread);
2021 } while (ret != 0xFFFFFFFF && ret != 0);
2022 if (ret == 0xFFFFFFFF) {
2023 WARN("bad Resume (%d)\n", GetLastError());
2025 } else {
2026 lpMidiStrm->dwStartTicks = GetTickCount() - lpMidiStrm->dwPositionMS;
2027 }
2028 }
2029 return ret;
2030}
2031
2032/**************************************************************************
2033 * midiStreamStop [WINMM.@]
2034 */
2035MMRESULT WINAPI midiStreamStop(HMIDISTRM hMidiStrm)
2036{
2037 WINE_MIDIStream* lpMidiStrm;
2039
2040 TRACE("(%p)!\n", hMidiStrm);
2041
2042 if (!MMSYSTEM_GetMidiStream(hMidiStrm, &lpMidiStrm, NULL)) {
2044 } else {
2045 /* in case stream has been paused... FIXME is the current state correct ? */
2046 midiStreamRestart(hMidiStrm);
2048 }
2049 return ret;
2050}
2051
2052static UINT WAVE_Open(HANDLE* lphndl, UINT uDeviceID, UINT uType,
2054 DWORD_PTR dwInstance, DWORD dwFlags)
2055{
2056 HANDLE handle;
2057 LPWINE_MLD wmld;
2058 DWORD dwRet;
2059 WAVEOPENDESC wod;
2060
2061 TRACE("(%p, %d, %s, %p, %08lX, %08lX, %08X);\n",
2062 lphndl, (int)uDeviceID, (uType==MMDRV_WAVEOUT)?"Out":"In", lpFormat, dwCallback,
2063 dwInstance, dwFlags);
2064
2066 TRACE("WAVE_FORMAT_QUERY requested !\n");
2067
2068 dwRet = WINMM_CheckCallback(dwCallback, dwFlags, FALSE);
2069 if (dwRet != MMSYSERR_NOERROR)
2070 return dwRet;
2071
2072 if (lpFormat == NULL) {
2073 WARN("bad format\n");
2074 return WAVERR_BADFORMAT;
2075 }
2076
2077 if ((dwFlags & WAVE_MAPPED) && (uDeviceID == (UINT)-1)) {
2078 WARN("invalid parameter\n");
2079 return MMSYSERR_INVALPARAM;
2080 }
2081
2082 /* may have a PCMWAVEFORMAT rather than a WAVEFORMATEX so don't read cbSize */
2083 TRACE("wFormatTag=%u, nChannels=%u, nSamplesPerSec=%u, nAvgBytesPerSec=%u, nBlockAlign=%u, wBitsPerSample=%u\n",
2084 lpFormat->wFormatTag, lpFormat->nChannels, lpFormat->nSamplesPerSec,
2085 lpFormat->nAvgBytesPerSec, lpFormat->nBlockAlign, lpFormat->wBitsPerSample);
2086
2087 if ((wmld = MMDRV_Alloc(sizeof(WINE_WAVE), uType, &handle,
2088 &dwFlags, &dwCallback, &dwInstance)) == NULL) {
2089 return MMSYSERR_NOMEM;
2090 }
2091
2092 wod.hWave = handle;
2093 wod.lpFormat = (LPWAVEFORMATEX)lpFormat; /* should the struct be copied iso pointer? */
2094 wod.dwCallback = dwCallback;
2095 wod.dwInstance = dwInstance;
2096 wod.dnDevNode = 0L;
2097
2098 TRACE("cb=%08lx\n", wod.dwCallback);
2099
2100 for (;;) {
2101 if (dwFlags & WAVE_MAPPED) {
2102 wod.uMappedDeviceID = uDeviceID;
2103 uDeviceID = WAVE_MAPPER;
2104 } else {
2105 wod.uMappedDeviceID = -1;
2106 }
2107 wmld->uDeviceID = uDeviceID;
2108
2109 dwRet = MMDRV_Open(wmld, (uType == MMDRV_WAVEOUT) ? WODM_OPEN : WIDM_OPEN,
2110 (DWORD_PTR)&wod, dwFlags);
2111
2112 TRACE("dwRet = %s\n", WINMM_ErrorToString(dwRet));
2113 if (dwRet != WAVERR_BADFORMAT ||
2114 ((dwFlags & (WAVE_MAPPED|WAVE_FORMAT_DIRECT)) != 0) || (uDeviceID == WAVE_MAPPER)) break;
2115 /* if we ask for a format which isn't supported by the physical driver,
2116 * let's try to map it through the wave mapper (except, if we already tried
2117 * or user didn't allow us to use acm codecs or the device is already the mapper)
2118 */
2120 /* we shall loop only one */
2121 }
2122
2123 if ((dwFlags & WAVE_FORMAT_QUERY) || dwRet != MMSYSERR_NOERROR) {
2124 MMDRV_Free(handle, wmld);
2125 handle = 0;
2126 }
2127
2128 if (lphndl != NULL) *lphndl = handle;
2129 TRACE("=> %s hWave=%p\n", WINMM_ErrorToString(dwRet), handle);
2130
2131 return dwRet;
2132}
2133
2134/**************************************************************************
2135 * waveOutGetNumDevs [WINMM.@]
2136 */
2138{
2140}
2141
2142/**************************************************************************
2143 * waveOutGetDevCapsA [WINMM.@]
2144 */
2146 UINT uSize)
2147{
2148 WAVEOUTCAPSW wocW;
2149 UINT ret;
2150
2151 if (lpCaps == NULL) return MMSYSERR_INVALPARAM;
2152
2153 ret = waveOutGetDevCapsW(uDeviceID, &wocW, sizeof(wocW));
2154
2155 if (ret == MMSYSERR_NOERROR) {
2156 WAVEOUTCAPSA wocA;
2157 wocA.wMid = wocW.wMid;
2158 wocA.wPid = wocW.wPid;
2159 wocA.vDriverVersion = wocW.vDriverVersion;
2160 WideCharToMultiByte( CP_ACP, 0, wocW.szPname, -1, wocA.szPname,
2161 sizeof(wocA.szPname), NULL, NULL );
2162 wocA.dwFormats = wocW.dwFormats;
2163 wocA.wChannels = wocW.wChannels;
2164 wocA.dwSupport = wocW.dwSupport;
2165 memcpy(lpCaps, &wocA, min(uSize, sizeof(wocA)));
2166 }
2167 return ret;
2168}
2169
2170/**************************************************************************
2171 * waveOutGetDevCapsW [WINMM.@]
2172 */
2174 UINT uSize)
2175{
2176 LPWINE_MLD wmld;
2177
2178 TRACE("(%lu %p %u)!\n", uDeviceID, lpCaps, uSize);
2179
2180 if (lpCaps == NULL) return MMSYSERR_INVALPARAM;
2181
2182 if (uDeviceID == WAVE_MAPPER)
2183 {
2184 FIXME("Support WAVE_MAPPER\n");
2185 uDeviceID = 0;
2186 }
2187
2188 if ((wmld = MMDRV_Get((HANDLE)uDeviceID, MMDRV_WAVEOUT, TRUE)) == NULL)
2189 return MMSYSERR_BADDEVICEID;
2190
2191 return MMDRV_Message(wmld, WODM_GETDEVCAPS, (DWORD_PTR)lpCaps, uSize);
2192}
2193
2194/**************************************************************************
2195 * waveOutGetErrorTextA [WINMM.@]
2196 * waveInGetErrorTextA [WINMM.@]
2197 */
2199{
2200 UINT ret;
2201
2202 if (lpText == NULL) ret = MMSYSERR_INVALPARAM;
2203 else if (uSize == 0) ret = MMSYSERR_NOERROR;
2204 else
2205 {
2206 LPWSTR xstr = HeapAlloc(GetProcessHeap(), 0, uSize * sizeof(WCHAR));
2207 if (!xstr) ret = MMSYSERR_NOMEM;
2208 else
2209 {
2210 ret = waveOutGetErrorTextW(uError, xstr, uSize);
2211 if (ret == MMSYSERR_NOERROR)
2212 WideCharToMultiByte(CP_ACP, 0, xstr, -1, lpText, uSize, NULL, NULL);
2213 HeapFree(GetProcessHeap(), 0, xstr);
2214 }
2215 }
2216 return ret;
2217}
2218
2219/**************************************************************************
2220 * waveOutGetErrorTextW [WINMM.@]
2221 * waveInGetErrorTextW [WINMM.@]
2222 */
2224{
2226
2227 if (lpText == NULL) ret = MMSYSERR_INVALPARAM;
2228 else if (uSize == 0) ret = MMSYSERR_NOERROR;
2229 else if (
2230 /* test has been removed because MMSYSERR_BASE is 0, and gcc did emit
2231 * a warning for the test was always true */
2232 (/*uError >= MMSYSERR_BASE && */ uError <= MMSYSERR_LASTERROR) ||
2233 (uError >= WAVERR_BASE && uError <= WAVERR_LASTERROR)) {
2235 uError, lpText, uSize) > 0) {
2237 }
2238 }
2239 return ret;
2240}
2241
2242/**************************************************************************
2243 * waveOutOpen [WINMM.@]
2244 * All the args/structs have the same layout as the win16 equivalents
2245 */
2248 DWORD_PTR dwInstance, DWORD dwFlags)
2249{
2250 return WAVE_Open((HANDLE*)lphWaveOut, uDeviceID, MMDRV_WAVEOUT, lpFormat,
2251 dwCallback, dwInstance, dwFlags);
2252}
2253
2254/**************************************************************************
2255 * waveOutClose [WINMM.@]
2256 */
2257UINT WINAPI waveOutClose(HWAVEOUT hWaveOut)
2258{
2259 LPWINE_MLD wmld;
2260 DWORD dwRet;
2261
2262 TRACE("(%p)\n", hWaveOut);
2263
2264 if ((wmld = MMDRV_Get(hWaveOut, MMDRV_WAVEOUT, FALSE)) == NULL)
2265 return MMSYSERR_INVALHANDLE;
2266
2267 dwRet = MMDRV_Close(wmld, WODM_CLOSE);
2268 if (dwRet != WAVERR_STILLPLAYING)
2269 MMDRV_Free(hWaveOut, wmld);
2270
2271 return dwRet;
2272}
2273
2274/**************************************************************************
2275 * waveOutPrepareHeader [WINMM.@]
2276 */
2278 WAVEHDR* lpWaveOutHdr, UINT uSize)
2279{
2280 LPWINE_MLD wmld;
2281 UINT result;
2282
2283 TRACE("(%p, %p, %u);\n", hWaveOut, lpWaveOutHdr, uSize);
2284
2285 if (lpWaveOutHdr == NULL || uSize < sizeof (WAVEHDR))
2286 return MMSYSERR_INVALPARAM;
2287
2288 if ((wmld = MMDRV_Get(hWaveOut, MMDRV_WAVEOUT, FALSE)) == NULL)
2289 return MMSYSERR_INVALHANDLE;
2290
2291 if ((result = MMDRV_Message(wmld, WODM_PREPARE, (DWORD_PTR)lpWaveOutHdr,
2292 uSize)) != MMSYSERR_NOTSUPPORTED)
2293 return result;
2294
2295 if (lpWaveOutHdr->dwFlags & WHDR_INQUEUE)
2296 return WAVERR_STILLPLAYING;
2297
2298 lpWaveOutHdr->dwFlags |= WHDR_PREPARED;
2299 lpWaveOutHdr->dwFlags &= ~WHDR_DONE;
2300
2301 return MMSYSERR_NOERROR;
2302}
2303
2304/**************************************************************************
2305 * waveOutUnprepareHeader [WINMM.@]
2306 */
2308 LPWAVEHDR lpWaveOutHdr, UINT uSize)
2309{
2310 LPWINE_MLD wmld;
2311 UINT result;
2312
2313 TRACE("(%p, %p, %u);\n", hWaveOut, lpWaveOutHdr, uSize);
2314
2315 if (lpWaveOutHdr == NULL || uSize < sizeof (WAVEHDR))
2316 return MMSYSERR_INVALPARAM;
2317
2318 if (!(lpWaveOutHdr->dwFlags & WHDR_PREPARED)) {
2319 return MMSYSERR_NOERROR;
2320 }
2321
2322 if ((wmld = MMDRV_Get(hWaveOut, MMDRV_WAVEOUT, FALSE)) == NULL)
2323 return MMSYSERR_INVALHANDLE;
2324
2325 if ((result = MMDRV_Message(wmld, WODM_UNPREPARE, (DWORD_PTR)lpWaveOutHdr,
2326 uSize)) != MMSYSERR_NOTSUPPORTED)
2327 return result;
2328
2329 if (lpWaveOutHdr->dwFlags & WHDR_INQUEUE)
2330 return WAVERR_STILLPLAYING;
2331
2332 lpWaveOutHdr->dwFlags &= ~WHDR_PREPARED;
2333 lpWaveOutHdr->dwFlags |= WHDR_DONE;
2334
2335 return MMSYSERR_NOERROR;
2336}
2337
2338/**************************************************************************
2339 * waveOutWrite [WINMM.@]
2340 */
2341UINT WINAPI waveOutWrite(HWAVEOUT hWaveOut, LPWAVEHDR lpWaveOutHdr,
2342 UINT uSize)
2343{
2344 LPWINE_MLD wmld;
2345
2346 TRACE("(%p, %p, %u);\n", hWaveOut, lpWaveOutHdr, uSize);
2347
2348 if ((wmld = MMDRV_Get(hWaveOut, MMDRV_WAVEOUT, FALSE)) == NULL)
2349 return MMSYSERR_INVALHANDLE;
2350
2351 return MMDRV_Message(wmld, WODM_WRITE, (DWORD_PTR)lpWaveOutHdr, uSize);
2352}
2353
2354/**************************************************************************
2355 * waveOutBreakLoop [WINMM.@]
2356 */
2357UINT WINAPI waveOutBreakLoop(HWAVEOUT hWaveOut)
2358{
2359 LPWINE_MLD wmld;
2360
2361 TRACE("(%p);\n", hWaveOut);
2362
2363 if ((wmld = MMDRV_Get(hWaveOut, MMDRV_WAVEOUT, FALSE)) == NULL)
2364 return MMSYSERR_INVALHANDLE;
2365 return MMDRV_Message(wmld, WODM_BREAKLOOP, 0L, 0L);
2366}
2367
2368/**************************************************************************
2369 * waveOutPause [WINMM.@]
2370 */
2371UINT WINAPI waveOutPause(HWAVEOUT hWaveOut)
2372{
2373 LPWINE_MLD wmld;
2374
2375 TRACE("(%p);\n", hWaveOut);
2376
2377 if ((wmld = MMDRV_Get(hWaveOut, MMDRV_WAVEOUT, FALSE)) == NULL)
2378 return MMSYSERR_INVALHANDLE;
2379 return MMDRV_Message(wmld, WODM_PAUSE, 0L, 0L);
2380}
2381
2382/**************************************************************************
2383 * waveOutReset [WINMM.@]
2384 */
2385UINT WINAPI waveOutReset(HWAVEOUT hWaveOut)
2386{
2387 LPWINE_MLD wmld;
2388
2389 TRACE("(%p);\n", hWaveOut);
2390
2391 if ((wmld = MMDRV_Get(hWaveOut, MMDRV_WAVEOUT, FALSE)) == NULL)
2392 return MMSYSERR_INVALHANDLE;
2393 return MMDRV_Message(wmld, WODM_RESET, 0L, 0L);
2394}
2395
2396/**************************************************************************
2397 * waveOutRestart [WINMM.@]
2398 */
2399UINT WINAPI waveOutRestart(HWAVEOUT hWaveOut)
2400{
2401 LPWINE_MLD wmld;
2402
2403 TRACE("(%p);\n", hWaveOut);
2404
2405 if ((wmld = MMDRV_Get(hWaveOut, MMDRV_WAVEOUT, FALSE)) == NULL)
2406 return MMSYSERR_INVALHANDLE;
2407 return MMDRV_Message(wmld, WODM_RESTART, 0L, 0L);
2408}
2409
2410/**************************************************************************
2411 * waveOutGetPosition [WINMM.@]
2412 */
2413UINT WINAPI waveOutGetPosition(HWAVEOUT hWaveOut, LPMMTIME lpTime,
2414 UINT uSize)
2415{
2416 LPWINE_MLD wmld;
2417
2418 TRACE("(%p, %p, %u);\n", hWaveOut, lpTime, uSize);
2419
2420 if ((wmld = MMDRV_Get(hWaveOut, MMDRV_WAVEOUT, FALSE)) == NULL)
2421 return MMSYSERR_INVALHANDLE;
2422
2423 return MMDRV_Message(wmld, WODM_GETPOS, (DWORD_PTR)lpTime, uSize);
2424}
2425
2426/**************************************************************************
2427 * waveOutGetPitch [WINMM.@]
2428 */
2429UINT WINAPI waveOutGetPitch(HWAVEOUT hWaveOut, LPDWORD lpdw)
2430{
2431 LPWINE_MLD wmld;
2432
2433 TRACE("(%p, %p);\n", hWaveOut, lpdw);
2434
2435 if ((wmld = MMDRV_Get(hWaveOut, MMDRV_WAVEOUT, FALSE)) == NULL)
2436 return MMSYSERR_INVALHANDLE;
2437 return MMDRV_Message(wmld, WODM_GETPITCH, (DWORD_PTR)lpdw, 0L);
2438}
2439
2440/**************************************************************************
2441 * waveOutSetPitch [WINMM.@]
2442 */
2444{
2445 LPWINE_MLD wmld;
2446
2447 TRACE("(%p, %08x);\n", hWaveOut, dw);
2448
2449 if ((wmld = MMDRV_Get(hWaveOut, MMDRV_WAVEOUT, FALSE)) == NULL)
2450 return MMSYSERR_INVALHANDLE;
2451 return MMDRV_Message(wmld, WODM_SETPITCH, dw, 0L);
2452}
2453
2454/**************************************************************************
2455 * waveOutGetPlaybackRate [WINMM.@]
2456 */
2458{
2459 LPWINE_MLD wmld;
2460
2461 TRACE("(%p, %p);\n", hWaveOut, lpdw);
2462
2463 if ((wmld = MMDRV_Get(hWaveOut, MMDRV_WAVEOUT, FALSE)) == NULL)
2464 return MMSYSERR_INVALHANDLE;
2465 return MMDRV_Message(wmld, WODM_GETPLAYBACKRATE, (DWORD_PTR)lpdw, 0L);
2466}
2467
2468/**************************************************************************
2469 * waveOutSetPlaybackRate [WINMM.@]
2470 */
2472{
2473 LPWINE_MLD wmld;
2474
2475 TRACE("(%p, %08x);\n", hWaveOut, dw);
2476
2477 if ((wmld = MMDRV_Get(hWaveOut, MMDRV_WAVEOUT, FALSE)) == NULL)
2478 return MMSYSERR_INVALHANDLE;
2479 return MMDRV_Message(wmld, WODM_SETPLAYBACKRATE, dw, 0L);
2480}
2481
2482/**************************************************************************
2483 * waveOutGetVolume [WINMM.@]
2484 */
2485UINT WINAPI waveOutGetVolume(HWAVEOUT hWaveOut, LPDWORD lpdw)
2486{
2487 LPWINE_MLD wmld;
2488
2489 TRACE("(%p, %p);\n", hWaveOut, lpdw);
2490
2491 if (lpdw == NULL) {
2492 WARN("invalid parameter\n");
2493 return MMSYSERR_INVALPARAM;
2494 }
2495
2496 if ((wmld = MMDRV_Get(hWaveOut, MMDRV_WAVEOUT, TRUE)) == NULL)
2497 return MMSYSERR_INVALHANDLE;
2498
2499 return MMDRV_Message(wmld, WODM_GETVOLUME, (DWORD_PTR)lpdw, 0L);
2500}
2501
2502/**************************************************************************
2503 * waveOutSetVolume [WINMM.@]
2504 */
2506{
2507 LPWINE_MLD wmld;
2508
2509 TRACE("(%p, %08x);\n", hWaveOut, dw);
2510
2511 if ((wmld = MMDRV_Get(hWaveOut, MMDRV_WAVEOUT, TRUE)) == NULL)
2512 return MMSYSERR_INVALHANDLE;
2513
2514 return MMDRV_Message(wmld, WODM_SETVOLUME, dw, 0L);
2515}
2516
2517/**************************************************************************
2518 * waveOutGetID [WINMM.@]
2519 */
2520UINT WINAPI waveOutGetID(HWAVEOUT hWaveOut, UINT* lpuDeviceID)
2521{
2522 LPWINE_MLD wmld;
2523
2524 TRACE("(%p, %p);\n", hWaveOut, lpuDeviceID);
2525
2526 if (lpuDeviceID == NULL) return MMSYSERR_INVALHANDLE;
2527
2528 if ((wmld = MMDRV_Get(hWaveOut, MMDRV_WAVEOUT, FALSE)) == NULL)
2529 return MMSYSERR_INVALHANDLE;
2530
2531 *lpuDeviceID = wmld->uDeviceID;
2532 return 0;
2533}
2534
2535/**************************************************************************
2536 * waveOutMessage [WINMM.@]
2537 */
2538UINT WINAPI waveOutMessage(HWAVEOUT hWaveOut, UINT uMessage,
2539 DWORD_PTR dwParam1, DWORD_PTR dwParam2)
2540{
2541 LPWINE_MLD wmld;
2542
2543 TRACE("(%p, %u, %ld, %ld)\n", hWaveOut, uMessage, dwParam1, dwParam2);
2544
2545 if ((wmld = MMDRV_Get(hWaveOut, MMDRV_WAVEOUT, FALSE)) == NULL) {
2546 if ((wmld = MMDRV_Get(hWaveOut, MMDRV_WAVEOUT, TRUE)) != NULL) {
2547 return MMDRV_PhysicalFeatures(wmld, uMessage, dwParam1, dwParam2);
2548 }
2549 WARN("invalid handle\n");
2550 return MMSYSERR_INVALHANDLE;
2551 }
2552
2553 /* from M$ KB */
2554 if (uMessage < DRVM_IOCTL || (uMessage >= DRVM_IOCTL_LAST && uMessage < DRVM_MAPPER)) {
2555 WARN("invalid parameter\n");
2556 return MMSYSERR_INVALPARAM;
2557 }
2558
2559 return MMDRV_Message(wmld, uMessage, dwParam1, dwParam2);
2560}
2561
2562/**************************************************************************
2563 * waveInGetNumDevs [WINMM.@]
2564 */
2566{
2567 return MMDRV_GetNum(MMDRV_WAVEIN);
2568}
2569
2570/**************************************************************************
2571 * waveInGetDevCapsW [WINMM.@]
2572 */
2574{
2575 LPWINE_MLD wmld;
2576
2577 TRACE("(%lu %p %u)!\n", uDeviceID, lpCaps, uSize);
2578
2579 if (lpCaps == NULL) return MMSYSERR_INVALPARAM;
2580
2581 if (uDeviceID == WAVE_MAPPER)
2582 {
2583 FIXME("Support WAVE_MAPPER\n");
2584 uDeviceID = 0;
2585 }
2586
2587
2588 if ((wmld = MMDRV_Get((HANDLE)uDeviceID, MMDRV_WAVEIN, TRUE)) == NULL)
2589 return MMSYSERR_BADDEVICEID;
2590
2591 return MMDRV_Message(wmld, WIDM_GETDEVCAPS, (DWORD_PTR)lpCaps, uSize);
2592}
2593
2594/**************************************************************************
2595 * waveInGetDevCapsA [WINMM.@]
2596 */
2598{
2599 WAVEINCAPSW wicW;
2600 UINT ret;
2601
2602 if (lpCaps == NULL) return MMSYSERR_INVALPARAM;
2603
2604 ret = waveInGetDevCapsW(uDeviceID, &wicW, sizeof(wicW));
2605
2606 if (ret == MMSYSERR_NOERROR) {
2607 WAVEINCAPSA wicA;
2608 wicA.wMid = wicW.wMid;
2609 wicA.wPid = wicW.wPid;
2610 wicA.vDriverVersion = wicW.vDriverVersion;
2611 WideCharToMultiByte( CP_ACP, 0, wicW.szPname, -1, wicA.szPname,
2612 sizeof(wicA.szPname), NULL, NULL );
2613 wicA.dwFormats = wicW.dwFormats;
2614 wicA.wChannels = wicW.wChannels;
2615 memcpy(lpCaps, &wicA, min(uSize, sizeof(wicA)));
2616 }
2617 return ret;
2618}
2619
2620/**************************************************************************
2621 * waveInOpen [WINMM.@]
2622 */
2623MMRESULT WINAPI waveInOpen(HWAVEIN* lphWaveIn, UINT uDeviceID,
2625 DWORD_PTR dwInstance, DWORD dwFlags)
2626{
2627 return WAVE_Open((HANDLE*)lphWaveIn, uDeviceID, MMDRV_WAVEIN, lpFormat,
2628 dwCallback, dwInstance, dwFlags);
2629}
2630
2631/**************************************************************************
2632 * waveInClose [WINMM.@]
2633 */
2634UINT WINAPI waveInClose(HWAVEIN hWaveIn)
2635{
2636 LPWINE_MLD wmld;
2637 DWORD dwRet;
2638
2639 TRACE("(%p)\n", hWaveIn);
2640
2641 if ((wmld = MMDRV_Get(hWaveIn, MMDRV_WAVEIN, FALSE)) == NULL)
2642 return MMSYSERR_INVALHANDLE;
2643
2644 dwRet = MMDRV_Message(wmld, WIDM_CLOSE, 0L, 0L);
2645 if (dwRet != WAVERR_STILLPLAYING)
2646 MMDRV_Free(hWaveIn, wmld);
2647 return dwRet;
2648}
2649
2650/**************************************************************************
2651 * waveInPrepareHeader [WINMM.@]
2652 */
2653UINT WINAPI waveInPrepareHeader(HWAVEIN hWaveIn, WAVEHDR* lpWaveInHdr,
2654 UINT uSize)
2655{
2656 LPWINE_MLD wmld;
2657 UINT result;
2658
2659 TRACE("(%p, %p, %u);\n", hWaveIn, lpWaveInHdr, uSize);
2660
2661 if (lpWaveInHdr == NULL || uSize < sizeof (WAVEHDR))
2662 return MMSYSERR_INVALPARAM;
2663
2664 if ((wmld = MMDRV_Get(hWaveIn, MMDRV_WAVEIN, FALSE)) == NULL)
2665 return MMSYSERR_INVALHANDLE;
2666
2667 if ((result = MMDRV_Message(wmld, WIDM_PREPARE, (DWORD_PTR)lpWaveInHdr,
2668 uSize)) != MMSYSERR_NOTSUPPORTED)
2669 return result;
2670
2671 if (lpWaveInHdr->dwFlags & WHDR_INQUEUE)
2672 return WAVERR_STILLPLAYING;
2673
2674 lpWaveInHdr->dwFlags |= WHDR_PREPARED;
2675 lpWaveInHdr->dwFlags &= ~WHDR_DONE;
2676 lpWaveInHdr->dwBytesRecorded = 0;
2677
2678 return MMSYSERR_NOERROR;
2679}
2680
2681/**************************************************************************
2682 * waveInUnprepareHeader [WINMM.@]
2683 */
2684UINT WINAPI waveInUnprepareHeader(HWAVEIN hWaveIn, WAVEHDR* lpWaveInHdr,
2685 UINT uSize)
2686{
2687 LPWINE_MLD wmld;
2688 UINT result;
2689
2690 TRACE("(%p, %p, %u);\n", hWaveIn, lpWaveInHdr, uSize);
2691
2692 if (lpWaveInHdr == NULL || uSize < sizeof (WAVEHDR))
2693 return MMSYSERR_INVALPARAM;
2694
2695 if (!(lpWaveInHdr->dwFlags & WHDR_PREPARED))
2696 return MMSYSERR_NOERROR;
2697
2698 if ((wmld = MMDRV_Get(hWaveIn, MMDRV_WAVEIN, FALSE)) == NULL)
2699 return MMSYSERR_INVALHANDLE;
2700
2701 if ((result = MMDRV_Message(wmld, WIDM_UNPREPARE, (DWORD_PTR)lpWaveInHdr,
2702 uSize)) != MMSYSERR_NOTSUPPORTED)
2703 return result;
2704
2705 if (lpWaveInHdr->dwFlags & WHDR_INQUEUE)
2706 return WAVERR_STILLPLAYING;
2707
2708 lpWaveInHdr->dwFlags &= ~WHDR_PREPARED;
2709 lpWaveInHdr->dwFlags |= WHDR_DONE;
2710
2711 return MMSYSERR_NOERROR;
2712}
2713
2714/**************************************************************************
2715 * waveInAddBuffer [WINMM.@]
2716 */
2718 WAVEHDR* lpWaveInHdr, UINT uSize)
2719{
2720 LPWINE_MLD wmld;
2721
2722 TRACE("(%p, %p, %u);\n", hWaveIn, lpWaveInHdr, uSize);
2723
2724 if (lpWaveInHdr == NULL) return MMSYSERR_INVALPARAM;
2725 if ((wmld = MMDRV_Get(hWaveIn, MMDRV_WAVEIN, FALSE)) == NULL)
2726 return MMSYSERR_INVALHANDLE;
2727
2728 return MMDRV_Message(wmld, WIDM_ADDBUFFER, (DWORD_PTR)lpWaveInHdr, uSize);
2729}
2730
2731/**************************************************************************
2732 * waveInReset [WINMM.@]
2733 */
2734UINT WINAPI waveInReset(HWAVEIN hWaveIn)
2735{
2736 LPWINE_MLD wmld;
2737
2738 TRACE("(%p);\n", hWaveIn);
2739
2740 if ((wmld = MMDRV_Get(hWaveIn, MMDRV_WAVEIN, FALSE)) == NULL)
2741 return MMSYSERR_INVALHANDLE;
2742
2743 return MMDRV_Message(wmld, WIDM_RESET, 0L, 0L);
2744}
2745
2746/**************************************************************************
2747 * waveInStart [WINMM.@]
2748 */
2749UINT WINAPI waveInStart(HWAVEIN hWaveIn)
2750{
2751 LPWINE_MLD wmld;
2752
2753 TRACE("(%p);\n", hWaveIn);
2754
2755 if ((wmld = MMDRV_Get(hWaveIn, MMDRV_WAVEIN, FALSE)) == NULL)
2756 return MMSYSERR_INVALHANDLE;
2757
2758 return MMDRV_Message(wmld, WIDM_START, 0L, 0L);
2759}
2760
2761/**************************************************************************
2762 * waveInStop [WINMM.@]
2763 */
2764UINT WINAPI waveInStop(HWAVEIN hWaveIn)
2765{
2766 LPWINE_MLD wmld;
2767
2768 TRACE("(%p);\n", hWaveIn);
2769
2770 if ((wmld = MMDRV_Get(hWaveIn, MMDRV_WAVEIN, FALSE)) == NULL)
2771 return MMSYSERR_INVALHANDLE;
2772
2773 return MMDRV_Message(wmld,WIDM_STOP, 0L, 0L);
2774}
2775
2776/**************************************************************************
2777 * waveInGetPosition [WINMM.@]
2778 */
2779UINT WINAPI waveInGetPosition(HWAVEIN hWaveIn, LPMMTIME lpTime,
2780 UINT uSize)
2781{
2782 LPWINE_MLD wmld;
2783
2784 TRACE("(%p, %p, %u);\n", hWaveIn, lpTime, uSize);
2785
2786 if ((wmld = MMDRV_Get(hWaveIn, MMDRV_WAVEIN, FALSE)) == NULL)
2787 return MMSYSERR_INVALHANDLE;
2788
2789 return MMDRV_Message(wmld, WIDM_GETPOS, (DWORD_PTR)lpTime, uSize);
2790}
2791
2792/**************************************************************************
2793 * waveInGetID [WINMM.@]
2794 */
2795UINT WINAPI waveInGetID(HWAVEIN hWaveIn, UINT* lpuDeviceID)
2796{
2797 LPWINE_MLD wmld;
2798
2799 TRACE("(%p, %p);\n", hWaveIn, lpuDeviceID);
2800
2801 if (lpuDeviceID == NULL) return MMSYSERR_INVALHANDLE;
2802
2803 if ((wmld = MMDRV_Get(hWaveIn, MMDRV_WAVEIN, FALSE)) == NULL)
2804 return MMSYSERR_INVALHANDLE;
2805
2806 *lpuDeviceID = wmld->uDeviceID;
2807 return MMSYSERR_NOERROR;
2808}
2809
2810/**************************************************************************
2811 * waveInMessage [WINMM.@]
2812 */
2813UINT WINAPI waveInMessage(HWAVEIN hWaveIn, UINT uMessage,
2814 DWORD_PTR dwParam1, DWORD_PTR dwParam2)
2815{
2816 LPWINE_MLD wmld;
2817
2818 TRACE("(%p, %u, %ld, %ld)\n", hWaveIn, uMessage, dwParam1, dwParam2);
2819
2820 if ((wmld = MMDRV_Get(hWaveIn, MMDRV_WAVEIN, FALSE)) == NULL) {
2821 if ((wmld = MMDRV_Get(hWaveIn, MMDRV_WAVEIN, TRUE)) != NULL) {
2822 return MMDRV_PhysicalFeatures(wmld, uMessage, dwParam1, dwParam2);
2823 }
2824 return MMSYSERR_INVALHANDLE;
2825 }
2826
2827 /* from M$ KB */
2828 if (uMessage < DRVM_IOCTL || (uMessage >= DRVM_IOCTL_LAST && uMessage < DRVM_MAPPER))
2829 return MMSYSERR_INVALPARAM;
2830
2831
2832 return MMDRV_Message(wmld, uMessage, dwParam1, dwParam2);
2833}
2834
2836{
2840};
2841
2842static DWORD WINAPI mmTaskRun(void* pmt)
2843{
2844 struct mm_starter mms;
2845
2846 memcpy(&mms, pmt, sizeof(struct mm_starter));
2847 HeapFree(GetProcessHeap(), 0, pmt);
2848 mms.cb(mms.client);
2849 if (mms.event) SetEvent(mms.event);
2850 return 0;
2851}
2852
2853/******************************************************************
2854 * mmTaskCreate (WINMM.@)
2855 */
2857{
2859 HANDLE hEvent = 0;
2860 struct mm_starter *mms;
2861
2862 mms = HeapAlloc(GetProcessHeap(), 0, sizeof(struct mm_starter));
2863 if (mms == NULL) return TASKERR_OUTOFMEMORY;
2864
2865 mms->cb = cb;
2866 mms->client = client;
2867 if (ph) hEvent = CreateEventW(NULL, FALSE, FALSE, NULL);
2868 mms->event = hEvent;
2869
2870 hThread = CreateThread(0, 0, mmTaskRun, mms, 0, NULL);
2871 if (!hThread) {
2872 HeapFree(GetProcessHeap(), 0, mms);
2874 return TASKERR_OUTOFMEMORY;
2875 }
2877 if (ph) *ph = hEvent;
2879 return 0;
2880}
2881
2882/******************************************************************
2883 * mmTaskBlock (WINMM.@)
2884 */
2886{
2887 MSG msg;
2888
2889 do
2890 {
2891 GetMessageA(&msg, 0, 0, 0);
2892 if (msg.hwnd) DispatchMessageA(&msg);
2893 } while (msg.message != WM_USER);
2894}
2895
2896/******************************************************************
2897 * mmTaskSignal (WINMM.@)
2898 */
2900{
2901 return PostThreadMessageW(tid, WM_USER, 0, 0);
2902}
2903
2904/******************************************************************
2905 * mmTaskYield (WINMM.@)
2906 */
2908
2909/******************************************************************
2910 * mmGetCurrentTask (WINMM.@)
2911 */
2913{
2914 return GetCurrentThreadId();
2915}
#define msg(x)
Definition: auth_time.c:54
HWND hWnd
Definition: settings.c:17
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
DWORD LPVOID fImpLoad
Definition: misc.cpp:155
#define UlongToHandle(ul)
Definition: basetsd.h:97
#define FIXME(fmt,...)
Definition: debug.h:111
#define WARN(fmt,...)
Definition: debug.h:112
#define ERR(fmt,...)
Definition: debug.h:110
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
UINT uFlags
Definition: api.c:59
static WCHAR unknown[MAX_STRING_RESOURCE_LEN]
Definition: object.c:1605
#define CloseHandle
Definition: compat.h:739
#define GetProcessHeap()
Definition: compat.h:736
#define DLL_PROCESS_ATTACH
Definition: compat.h:131
#define DLL_PROCESS_DETACH
Definition: compat.h:130
#define CP_ACP
Definition: compat.h:109
HANDLE HWND
Definition: compat.h:19
#define GetProcAddress(x, y)
Definition: compat.h:753
#define HeapAlloc
Definition: compat.h:733
#define HeapFree(x, y, z)
Definition: compat.h:735
#define CALLBACK
Definition: compat.h:35
#define WideCharToMultiByte
Definition: compat.h:111
#define MultiByteToWideChar
Definition: compat.h:110
HMODULE WINAPI DECLSPEC_HOTPATCH GetModuleHandleA(LPCSTR lpModuleName)
Definition: loader.c:812
BOOL WINAPI DisableThreadLibraryCalls(IN HMODULE hLibModule)
Definition: loader.c:85
DWORD WINAPI ResumeThread(IN HANDLE hThread)
Definition: thread.c:567
BOOL WINAPI SetThreadPriority(IN HANDLE hThread, IN int nPriority)
Definition: thread.c:700
DWORD WINAPI SuspendThread(IN HANDLE hThread)
Definition: thread.c:642
VOID WINAPI ExitThread(IN DWORD uExitCode)
Definition: thread.c:365
HANDLE WINAPI DECLSPEC_HOTPATCH CreateThread(IN LPSECURITY_ATTRIBUTES lpThreadAttributes, IN DWORD dwStackSize, IN LPTHREAD_START_ROUTINE lpStartAddress, IN LPVOID lpParameter, IN DWORD dwCreationFlags, OUT LPDWORD lpThreadId)
Definition: thread.c:137
DWORD WINAPI GetTickCount(VOID)
Definition: time.c:455
#define MODM_GETDEVCAPS
Definition: mmddk.h:155
#define WODM_PREPARE
Definition: mmddk.h:112
#define WODM_SETVOLUME
Definition: mmddk.h:122
#define MIDM_OPEN
Definition: mmddk.h:171
#define MIDM_UNPREPARE
Definition: mmddk.h:174
#define MIDM_START
Definition: mmddk.h:176
#define MODM_PREPARE
Definition: mmddk.h:158
#define MIDM_ADDBUFFER
Definition: mmddk.h:175
#define WODM_OPEN
Definition: mmddk.h:110
#define MIDM_PREPARE
Definition: mmddk.h:173
#define WIDM_STOP
Definition: mmddk.h:144
#define WODM_RESET
Definition: mmddk.h:117
TASKCALLBACK FAR * LPTASKCALLBACK
Definition: mmddk.h:33
#define DRVM_IOCTL_LAST
Definition: mmddk.h:69
#define AUXDM_GETDEVCAPS
Definition: mmddk.h:183
#define WODM_GETVOLUME
Definition: mmddk.h:121
#define MIDM_RESET
Definition: mmddk.h:178
#define MIDM_STOP
Definition: mmddk.h:177
#define AUXDM_GETVOLUME
Definition: mmddk.h:184
#define MXDM_GETCONTROLDETAILS
Definition: mmddk.h:197
#define WODM_WRITE
Definition: mmddk.h:114
#define MXDM_GETLINECONTROLS
Definition: mmddk.h:196
#define MODM_RESET
Definition: mmddk.h:162
#define WODM_RESTART
Definition: mmddk.h:116
#define MODM_DATA
Definition: mmddk.h:160
#define MXDM_SETCONTROLDETAILS
Definition: mmddk.h:198
#define WODM_GETPITCH
Definition: mmddk.h:119
#define MODM_GETVOLUME
Definition: mmddk.h:163
#define DRVM_IOCTL
Definition: mmddk.h:66
#define WIDM_START
Definition: mmddk.h:143
#define MXDM_OPEN
Definition: mmddk.h:193
#define MODM_OPEN
Definition: mmddk.h:156
#define WODM_SETPLAYBACKRATE
Definition: mmddk.h:124
#define WODM_GETPOS
Definition: mmddk.h:118
#define MODM_SETVOLUME
Definition: mmddk.h:164
#define WODM_SETPITCH
Definition: mmddk.h:120
#define MXDM_GETDEVCAPS
Definition: mmddk.h:192
#define WODM_GETPLAYBACKRATE
Definition: mmddk.h:123
#define MODM_UNPREPARE
Definition: mmddk.h:159
#define WIDM_GETDEVCAPS
Definition: mmddk.h:137
#define MXDM_GETLINEINFO
Definition: mmddk.h:195
#define WODM_GETDEVCAPS
Definition: mmddk.h:109
#define MIDM_CLOSE
Definition: mmddk.h:172
#define WIDM_CLOSE
Definition: mmddk.h:139
#define WIDM_PREPARE
Definition: mmddk.h:140
#define MIDM_GETDEVCAPS
Definition: mmddk.h:170
BOOL WINAPI DriverCallback(DWORD dwCallBack, UINT uFlags, HDRVR hDev, UINT wMsg, DWORD dwUser, DWORD dwParam1, DWORD dwParam2)
#define WIDM_GETPOS
Definition: mmddk.h:146
#define WIDM_ADDBUFFER
Definition: mmddk.h:142
#define AUXDM_SETVOLUME
Definition: mmddk.h:185
#define WODM_CLOSE
Definition: mmddk.h:111
#define MODM_LONGDATA
Definition: mmddk.h:161
#define MXDM_CLOSE
Definition: mmddk.h:194
#define MODM_CLOSE
Definition: mmddk.h:157
#define WIDM_RESET
Definition: mmddk.h:145
#define WIDM_UNPREPARE
Definition: mmddk.h:141
#define WODM_UNPREPARE
Definition: mmddk.h:113
#define WODM_PAUSE
Definition: mmddk.h:115
#define WODM_BREAKLOOP
Definition: mmddk.h:125
#define WIDM_OPEN
Definition: mmddk.h:138
unsigned char
Definition: typeof.h:29
void DRIVER_UnloadAll(void)
Definition: driver.c:658
DWORD MCI_SendCommand(UINT wDevID, UINT16 wMsg, DWORD_PTR dwParam1, DWORD_PTR dwParam2)
Definition: mci.c:2075
void TIME_MMTimeStop(void)
Definition: time.c:271
#define INFINITE
Definition: serial.h:102
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
unsigned short WORD
Definition: ntddk_ex.h:93
#define printf
Definition: freeldr.h:97
GLsizeiptr size
Definition: glext.h:5919
GLuint64EXT * result
Definition: glext.h:11304
GLfloat GLfloat GLfloat GLfloat h
Definition: glext.h:7723
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
static int mod
Definition: i386-dis.c:1288
REFIID LPVOID DWORD_PTR dw
Definition: atlbase.h:40
#define LOBYTE(W)
Definition: jmemdos.c:487
#define HIBYTE(W)
Definition: jmemdos.c:486
DWORD MMDRV_Open(LPWINE_MLD mld, UINT wMsg, DWORD_PTR dwParam1, DWORD dwFlags)
Definition: lolvldrv.c:183
DWORD MMDRV_Close(LPWINE_MLD mld, UINT wMsg)
Definition: lolvldrv.c:228
void MMDRV_Exit(void)
Definition: lolvldrv.c:611
DWORD MMDRV_Message(LPWINE_MLD mld, UINT wMsg, DWORD_PTR dwParam1, DWORD_PTR dwParam2)
Definition: lolvldrv.c:71
LPWINE_MLD MMDRV_GetRelated(HANDLE hndl, UINT srcType, BOOL bSrcCanBeID, UINT dstType)
Definition: lolvldrv.c:285
BOOL MMDRV_Init(void)
Definition: lolvldrv.c:530
void MMDRV_Free(HANDLE hndl, LPWINE_MLD mld)
Definition: lolvldrv.c:165
LPWINE_MLD MMDRV_Alloc(UINT size, UINT type, LPHANDLE hndl, DWORD *dwFlags, DWORD_PTR *dwCallback, DWORD_PTR *dwInstance)
Definition: lolvldrv.c:123
UINT MMDRV_PhysicalFeatures(LPWINE_MLD mld, UINT uMsg, DWORD_PTR dwParam1, DWORD_PTR dwParam2)
Definition: lolvldrv.c:303
UINT MMDRV_GetNum(UINT type)
Definition: lolvldrv.c:61
LPWINE_MLD MMDRV_Get(HANDLE _hndl, UINT type, BOOL bCanBeID)
Definition: lolvldrv.c:250
#define error(str)
Definition: mkdosfs.c:1605
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
struct _WAVEFORMATEX * LPWAVEFORMATEX
#define DRVM_MAPPER
Definition: mmsys.h:38
#define CALLBACK_WINDOW
Definition: mmsystem.h:148
#define WAVERR_STILLPLAYING
Definition: mmsystem.h:177
#define MIXER_OBJECTF_MIDIOUT
Definition: mmsystem.h:306
#define WAVERR_BASE
Definition: mmsystem.h:85
struct midievent_tag MIDIEVENT
#define MEVT_EVENTPARM(x)
Definition: mmsystem.h:276
#define MMSYSERR_NOMEM
Definition: mmsystem.h:103
#define MEVT_COMMENT
Definition: mmsystem.h:281
#define MIXER_OBJECTF_MIXER
Definition: mmsystem.h:300
#define MIDIERR_BASE
Definition: mmsystem.h:86
#define TIME_TICKS
Definition: mmsystem.h:33
#define MIXER_OBJECTF_AUX
Definition: mmsystem.h:310
UINT MMRESULT
Definition: mmsystem.h:962
#define MIXER_GETLINEINFOF_LINEID
Definition: mmsystem.h:346
#define CALLBACK_TYPEMASK
Definition: mmsystem.h:146
#define MMSYSERR_HANDLEBUSY
Definition: mmsystem.h:108
#define MMSYSERR_BADDB
Definition: mmsystem.h:110
#define MMSYSERR_NOTSUPPORTED
Definition: mmsystem.h:104
#define WAVE_FORMAT_QUERY
Definition: mmsystem.h:188
#define MIXER_GETLINECONTROLSF_QUERYMASK
Definition: mmsystem.h:411
#define MIDIERR_INVALIDSETUP
Definition: mmsystem.h:236
#define CALLBACK_THREAD
Definition: mmsystem.h:151
#define MIXER_OBJECTF_WAVEOUT
Definition: mmsystem.h:302
#define MIDIPROP_TEMPO
Definition: mmsystem.h:287
HMIDIOUT * LPHMIDIOUT
Definition: mmsystem.h:1101
#define MIXER_GETCONTROLDETAILSF_VALUE
Definition: mmsystem.h:412
#define MIXER_OBJECTF_MIDIIN
Definition: mmsystem.h:308
#define MIXER_GETLINEINFOF_TARGETTYPE
Definition: mmsystem.h:348
#define MIDIERR_NODEVICE
Definition: mmsystem.h:235
#define MMSYSERR_NODRIVER
Definition: mmsystem.h:102
#define MIDIERR_UNPREPARED
Definition: mmsystem.h:231
#define MIXER_GETCONTROLDETAILSF_QUERYMASK
Definition: mmsystem.h:414
HMIXER * LPHMIXER
Definition: mmsystem.h:1211
#define MIDIPROP_TIMEDIV
Definition: mmsystem.h:286
#define WAVE_MAPPER
Definition: mmsystem.h:187
#define MMSYSERR_DELETEERROR
Definition: mmsystem.h:114
#define MHDR_PREPARED
Definition: mmsystem.h:269
#define MIXER_GETLINEINFOF_DESTINATION
Definition: mmsystem.h:344
#define WAVERR_LASTERROR
Definition: mmsystem.h:180
#define MCI_ALL_DEVICE_ID
Definition: mmsystem.h:679
#define MMSYSERR_NODRIVERCB
Definition: mmsystem.h:116
#define MIXER_OBJECTF_HMIDIOUT
Definition: mmsystem.h:307
HWAVEOUT * LPHWAVEOUT
Definition: mmsystem.h:1009
struct tagMIXERCONTROLW MIXERCONTROLW
#define MCI_CLOSE
Definition: mmsystem.h:647
#define WHDR_INQUEUE
Definition: mmsystem.h:197
#define MEVT_F_LONG
Definition: mmsystem.h:273
#define CALLBACK_EVENT
Definition: mmsystem.h:152
#define MIXER_GETCONTROLDETAILSF_LISTTEXT
Definition: mmsystem.h:413
#define MIXER_GETLINEINFOF_COMPONENTTYPE
Definition: mmsystem.h:347
#define MIXER_OBJECTF_WAVEIN
Definition: mmsystem.h:304
#define MIDIPROP_GET
Definition: mmsystem.h:285
#define MMSYSERR_LASTERROR
Definition: mmsystem.h:118
#define MEVT_F_CALLBACK
Definition: mmsystem.h:274
#define MHDR_INQUEUE
Definition: mmsystem.h:270
#define MEVT_SHORTMSG
Definition: mmsystem.h:277
#define MMSYSERR_VALNOTFOUND
Definition: mmsystem.h:115
#define MMSYSERR_INVALHANDLE
Definition: mmsystem.h:101
struct tagMIXERCONTROLDETAILS_LISTTEXTA MIXERCONTROLDETAILS_LISTTEXTA
#define MMSYSERR_WRITEERROR
Definition: mmsystem.h:113
#define MIXER_GETLINEINFOF_SOURCE
Definition: mmsystem.h:345
#define MMSYSERR_INVALPARAM
Definition: mmsystem.h:107
#define MIDIPROP_SET
Definition: mmsystem.h:284
#define MMSYSERR_NOERROR
Definition: mmsystem.h:96
#define MEVT_TEMPO
Definition: mmsystem.h:278
#define WAVERR_BADFORMAT
Definition: mmsystem.h:176
#define MMSYSERR_ALLOCATED
Definition: mmsystem.h:100
#define WAVE_MAPPED
Definition: mmsystem.h:190
#define MMSYSERR_ERROR
Definition: mmsystem.h:97
#define MIDIERR_STILLPLAYING
Definition: mmsystem.h:232
#define MMSYSERR_READERROR
Definition: mmsystem.h:112
#define MIXER_GETLINECONTROLSF_ONEBYTYPE
Definition: mmsystem.h:410
#define MIXER_OBJECTF_HWAVEIN
Definition: mmsystem.h:305
#define MM_MOM_POSITIONCB
Definition: mmsystem.h:79
#define MEVT_EVENTTYPE(x)
Definition: mmsystem.h:275
#define MEVT_LONGMSG
Definition: mmsystem.h:280
#define WHDR_PREPARED
Definition: mmsystem.h:194
#define MMSYSERR_INVALFLAG
Definition: mmsystem.h:106
#define MCI_WAIT
Definition: mmsystem.h:730
#define CALLBACK_FUNCTION
Definition: mmsystem.h:150
struct tagMIXERCONTROLDETAILS_LISTTEXTW MIXERCONTROLDETAILS_LISTTEXTW
#define MHDR_ISSTRM
Definition: mmsystem.h:271
#define MIXER_OBJECTF_HMIDIIN
Definition: mmsystem.h:309
#define TIME_MS
Definition: mmsystem.h:28
#define MHDR_DONE
Definition: mmsystem.h:268
#define MMSYSERR_KEYNOTFOUND
Definition: mmsystem.h:111
#define MEVT_NOP
Definition: mmsystem.h:279
#define MIXER_GETLINEINFOF_QUERYMASK
Definition: mmsystem.h:349
#define MIDIERR_LASTERROR
Definition: mmsystem.h:239
#define MIXER_OBJECTF_HMIXER
Definition: mmsystem.h:301
struct midihdr_tag * LPMIDIHDR
#define MMSYSERR_BADDEVICEID
Definition: mmsystem.h:98
#define WAVERR_UNPREPARED
Definition: mmsystem.h:178
#define WHDR_DONE
Definition: mmsystem.h:193
#define MEVT_VERSION
Definition: mmsystem.h:282
#define WAVE_FORMAT_DIRECT
Definition: mmsystem.h:191
struct tagMIXERCONTROLA MIXERCONTROLA
#define MIXER_OBJECTF_HWAVEOUT
Definition: mmsystem.h:303
#define MM_MOM_DONE
Definition: mmsystem.h:70
#define MMSYSERR_NOTENABLED
Definition: mmsystem.h:99
#define CALLBACK_NULL
Definition: mmsystem.h:147
#define WAVERR_SYNC
Definition: mmsystem.h:179
#define MMSYSERR_INVALIDALIAS
Definition: mmsystem.h:109
#define MMSYSERR_BADERRNUM
Definition: mmsystem.h:105
#define sprintf(buf, format,...)
Definition: sprintf.c:55
static HANDLE hEvent
Definition: comm.c:54
static HMODULE MODULEINFO DWORD cb
Definition: module.c:33
static TfClientId tid
static const char mbstate_t *static wchar_t const char mbstate_t *static const wchar_t int *static double
Definition: string.c:80
BOOL loaded
Definition: xmlview.c:54
#define min(a, b)
Definition: monoChain.cc:55
unsigned __int3264 UINT_PTR
Definition: mstsclib_h.h:274
unsigned int UINT
Definition: ndis.h:50
HANDLE hThread
Definition: wizard.c:28
#define LPDWORD
Definition: nt_native.h:46
#define DWORD
Definition: nt_native.h:44
_In_ DWORD _In_ DWORD dwOffset
Definition: ntgdi.h:2033
#define L(x)
Definition: ntvdm.h:50
#define offsetof(TYPE, MEMBER)
void WINAPI mmTaskYield(void)
Definition: winmm.c:2907
#define TASKERR_OUTOFMEMORY
Definition: mmddk.h:474
DWORD WINAPI mmGetCurrentTask(void)
Definition: winmm.c:2912
static FILE * client
Definition: client.c:41
#define TRACE(s)
Definition: solgame.cpp:4
HMIDI hMidi
Definition: mmddk.h:412
DWORD cIds
Definition: mmddk.h:416
DWORD dwInstance
Definition: mmddk.h:414
DWORD dwCallback
Definition: mmddk.h:413
DWORD dnDevNode
Definition: mmddk.h:415
MIDIOPENSTRMID rgIds
Definition: mmddk.h:417
DWORD dwStreamID
Definition: mmddk.h:407
WORD wDeviceID
Definition: mmddk.h:408
LPWAVEFORMATEX lpFormat
Definition: mmddk.h:399
DWORD dnDevNode
Definition: mmddk.h:403
HWAVE hWave
Definition: mmddk.h:398
DWORD dwInstance
Definition: mmddk.h:401
DWORD dwCallback
Definition: mmddk.h:400
UINT uMappedDeviceID
Definition: mmddk.h:402
HANDLE hEvent
Definition: winmm.c:1463
LPMIDIHDR lpMidiHdr
Definition: winmm.c:1464
DWORD dwPulses
Definition: winmm.c:1460
HANDLE hThread
Definition: winmm.c:1455
DWORD dwStartTicks
Definition: winmm.c:1461
DWORD dwThreadID
Definition: winmm.c:1456
DWORD dwTempo
Definition: winmm.c:1457
HMIDIOUT hDevice
Definition: winmm.c:1454
DWORD dwTimeDiv
Definition: winmm.c:1458
DWORD dwPositionMS
Definition: winmm.c:1459
WINE_MLD mld
Definition: winemm.h:109
MIDIOPENDESC mod
Definition: winemm.h:110
WINE_MLD mld
Definition: winemm.h:114
DWORD dwBufferLength
Definition: mmsystem.h:1152
DWORD dwOffset
Definition: mmsystem.h:1158
struct midihdr_tag * lpNext
Definition: mmsystem.h:1156
DWORD dwFlags
Definition: mmsystem.h:1155
DWORD dwBytesRecorded
Definition: mmsystem.h:1153
LPSTR lpData
Definition: mmsystem.h:1151
DWORD client
Definition: winmm.c:2838
LPTASKCALLBACK cb
Definition: winmm.c:2837
HANDLE event
Definition: winmm.c:2839
DWORD ms
Definition: mmsystem.h:967
union mmtime_tag::@3042 u
UINT wType
Definition: mmsystem.h:965
DWORD ticks
Definition: mmsystem.h:970
DWORD dwSupport
Definition: mmsystem.h:1195
CHAR szPname[MAXPNAMELEN]
Definition: mmsystem.h:1192
MMVERSION vDriverVersion
Definition: mmsystem.h:1191
WORD wTechnology
Definition: mmsystem.h:1193
WORD wTechnology
Definition: mmsystem.h:1203
DWORD dwSupport
Definition: mmsystem.h:1205
MMVERSION vDriverVersion
Definition: mmsystem.h:1201
WCHAR szPname[MAXPNAMELEN]
Definition: mmsystem.h:1202
DWORD dwSupport
Definition: mmsystem.h:1139
MMVERSION vDriverVersion
Definition: mmsystem.h:1137
CHAR szPname[MAXPNAMELEN]
Definition: mmsystem.h:1138
MMVERSION vDriverVersion
Definition: mmsystem.h:1145
DWORD dwSupport
Definition: mmsystem.h:1147
WCHAR szPname[MAXPNAMELEN]
Definition: mmsystem.h:1146
MMVERSION vDriverVersion
Definition: mmsystem.h:1113
CHAR szPname[MAXPNAMELEN]
Definition: mmsystem.h:1114
MMVERSION vDriverVersion
Definition: mmsystem.h:1125
WCHAR szPname[MAXPNAMELEN]
Definition: mmsystem.h:1126
DWORD cDestinations
Definition: mmsystem.h:1219
DWORD fdwSupport
Definition: mmsystem.h:1218
MMVERSION vDriverVersion
Definition: mmsystem.h:1216
CHAR szPname[MAXPNAMELEN]
Definition: mmsystem.h:1217
DWORD cDestinations
Definition: mmsystem.h:1228
MMVERSION vDriverVersion
Definition: mmsystem.h:1225
DWORD fdwSupport
Definition: mmsystem.h:1227
WCHAR szPname[MAXPNAMELEN]
Definition: mmsystem.h:1226
union tagMIXERCONTROLA::@3048 Metrics
union tagMIXERCONTROLA::@3047 Bounds
CHAR szName[MIXER_LONG_NAME_CHARS]
Definition: mmsystem.h:1284
CHAR szShortName[MIXER_SHORT_NAME_CHARS]
Definition: mmsystem.h:1283
DWORD dwControlType
Definition: mmsystem.h:1280
DWORD cMultipleItems
Definition: mmsystem.h:1282
CHAR szName[MIXER_LONG_NAME_CHARS]
Definition: mmsystem.h:1368
WCHAR szName[MIXER_LONG_NAME_CHARS]
Definition: mmsystem.h:1374
WCHAR szName[MIXER_LONG_NAME_CHARS]
Definition: mmsystem.h:1310
DWORD dwControlType
Definition: mmsystem.h:1306
DWORD cMultipleItems
Definition: mmsystem.h:1308
union tagMIXERCONTROLW::@3051 Bounds
WCHAR szShortName[MIXER_SHORT_NAME_CHARS]
Definition: mmsystem.h:1309
union tagMIXERCONTROLW::@3052 Metrics
DWORD dwDestination
Definition: mmsystem.h:1233
CHAR szShortName[MIXER_SHORT_NAME_CHARS]
Definition: mmsystem.h:1242
DWORD dwComponentType
Definition: mmsystem.h:1238
struct tagMIXERLINEA::@3045 Target
DWORD cControls
Definition: mmsystem.h:1241
DWORD fdwLine
Definition: mmsystem.h:1236
DWORD dwLineID
Definition: mmsystem.h:1235
CHAR szName[MIXER_LONG_NAME_CHARS]
Definition: mmsystem.h:1243
DWORD dwSource
Definition: mmsystem.h:1234
DWORD_PTR dwUser
Definition: mmsystem.h:1237
DWORD cConnections
Definition: mmsystem.h:1240
DWORD cbStruct
Definition: mmsystem.h:1232
DWORD cChannels
Definition: mmsystem.h:1239
LPMIXERCONTROLA pamxctrl
Definition: mmsystem.h:1338
LPMIXERCONTROLW pamxctrl
Definition: mmsystem.h:1350
struct tagMIXERLINEW::@3046 Target
DWORD fdwLine
Definition: mmsystem.h:1259
DWORD dwDestination
Definition: mmsystem.h:1256
DWORD cControls
Definition: mmsystem.h:1264
DWORD dwSource
Definition: mmsystem.h:1257
DWORD dwLineID
Definition: mmsystem.h:1258
WCHAR szName[MIXER_LONG_NAME_CHARS]
Definition: mmsystem.h:1266
DWORD cChannels
Definition: mmsystem.h:1262
DWORD cConnections
Definition: mmsystem.h:1263
DWORD_PTR dwUser
Definition: mmsystem.h:1260
DWORD cbStruct
Definition: mmsystem.h:1255
DWORD dwComponentType
Definition: mmsystem.h:1261
WCHAR szShortName[MIXER_SHORT_NAME_CHARS]
Definition: mmsystem.h:1265
MMVERSION vDriverVersion
Definition: mmsystem.h:1049
DWORD dwFormats
Definition: mmsystem.h:1051
CHAR szPname[MAXPNAMELEN]
Definition: mmsystem.h:1050
WCHAR szPname[MAXPNAMELEN]
Definition: mmsystem.h:1060
MMVERSION vDriverVersion
Definition: mmsystem.h:1059
DWORD dwFormats
Definition: mmsystem.h:1061
CHAR szPname[MAXPNAMELEN]
Definition: mmsystem.h:1028
MMVERSION vDriverVersion
Definition: mmsystem.h:1027
MMVERSION vDriverVersion
Definition: mmsystem.h:1038
WCHAR szPname[MAXPNAMELEN]
Definition: mmsystem.h:1039
UINT uDeviceID
Definition: winemm.h:94
DWORD dwFlags
Definition: mmsystem.h:1018
DWORD dwBytesRecorded
Definition: mmsystem.h:1016
#define max(a, b)
Definition: svc.c:63
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
VOID WINAPI InitializeCriticalSection(OUT LPCRITICAL_SECTION lpCriticalSection)
Definition: synch.c:751
HANDLE WINAPI DECLSPEC_HOTPATCH CreateEventW(IN LPSECURITY_ATTRIBUTES lpEventAttributes OPTIONAL, IN BOOL bManualReset, IN BOOL bInitialState, IN LPCWSTR lpName OPTIONAL)
Definition: synch.c:651
BOOL WINAPI DECLSPEC_HOTPATCH SetEvent(IN HANDLE hEvent)
Definition: synch.c:733
LPCWSTR lpFormat
Definition: trayclock.cpp:32
#define DWORD_PTR
Definition: treelist.c:76
TW_UINT32 TW_UINT16 TW_UINT16 MSG
Definition: twain.h:1829
uint32_t DWORD_PTR
Definition: typedefs.h:65
unsigned char * LPBYTE
Definition: typedefs.h:53
PVOID HANDLE
Definition: typedefs.h:73
uint32_t * LPDWORD
Definition: typedefs.h:59
uint32_t ULONG_PTR
Definition: typedefs.h:65
uint32_t * LPUINT
Definition: typedefs.h:59
#define HIWORD(l)
Definition: typedefs.h:247
int ret
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
DWORD WINAPI GetCurrentThreadId(void)
Definition: thread.c:459
void WINAPI DeleteCriticalSection(PCRITICAL_SECTION)
#define WAIT_OBJECT_0
Definition: winbase.h:406
#define THREAD_PRIORITY_TIME_CRITICAL
Definition: winbase.h:281
_In_ PCCERT_CONTEXT _In_ DWORD dwFlags
Definition: wincrypt.h:1176
LONG_PTR LPARAM
Definition: windef.h:208
UINT_PTR WPARAM
Definition: windef.h:207
#define WINAPI
Definition: msvc.h:6
#define MMDRV_WAVEIN
Definition: winemm.h:80
#define MMDRV_AUX
Definition: winemm.h:76
#define MMDRV_MIDIIN
Definition: winemm.h:78
struct WINE_MIDI * LPWINE_MIDI
struct WINE_MIXER * LPWINE_MIXER
#define MMDRV_MIDIOUT
Definition: winemm.h:79
#define MMDRV_WAVEOUT
Definition: winemm.h:81
#define MMDRV_MIXER
Definition: winemm.h:77
UINT WINAPI mmTaskCreate(LPTASKCALLBACK cb, HANDLE *ph, DWORD_PTR client)
Definition: winmm.c:2856
UINT WINAPI mixerGetLineControlsW(HMIXEROBJ hmix, LPMIXERLINECONTROLSW lpmlcW, DWORD fdwControls)
Definition: winmm.c:571
UINT WINAPI auxGetVolume(UINT uDeviceID, DWORD *lpdwVolume)
Definition: winmm.c:765
MMRESULT WINAPI midiStreamPosition(HMIDISTRM hMidiStrm, LPMMTIME lpMMT, UINT cbmmt)
Definition: winmm.c:1925
UINT WINAPI midiInUnprepareHeader(HMIDIIN hMidiIn, MIDIHDR *lpMidiInHdr, UINT uSize)
Definition: winmm.c:1313
UINT WINAPI mixerClose(HMIXER hMix)
Definition: winmm.c:386
UINT WINAPI midiOutReset(HMIDIOUT hMidiOut)
Definition: winmm.c:1070
MMRESULT WINAPI midiStreamProperty(HMIDISTRM hMidiStrm, LPBYTE lpPropData, DWORD dwProperty)
Definition: winmm.c:1959
UINT WINAPI midiInStop(HMIDIIN hMidiIn)
Definition: winmm.c:1367
UINT WINAPI waveInGetPosition(HWAVEIN hWaveIn, LPMMTIME lpTime, UINT uSize)
Definition: winmm.c:2779
static void WINMM_DeleteIData(void)
Definition: winmm.c:69
UINT WINAPI mixerGetLineControlsA(HMIXEROBJ hmix, LPMIXERLINECONTROLSA lpmlcA, DWORD fdwControls)
Definition: winmm.c:503
MMRESULT WINAPI midiStreamRestart(HMIDISTRM hMidiStrm)
Definition: winmm.c:2004
UINT WINAPI waveOutGetDevCapsA(UINT_PTR uDeviceID, LPWAVEOUTCAPSA lpCaps, UINT uSize)
Definition: winmm.c:2145
UINT WINAPI midiInReset(HMIDIIN hMidiIn)
Definition: winmm.c:1382
static DWORD WINAPI mmTaskRun(void *pmt)
Definition: winmm.c:2842
UINT WINAPI waveOutGetErrorTextW(UINT uError, LPWSTR lpText, UINT uSize)
Definition: winmm.c:2223
HANDLE psLastEvent
Definition: winmm.c:51
UINT WINAPI waveOutReset(HWAVEOUT hWaveOut)
Definition: winmm.c:2385
static BOOL WINMM_CreateIData(HINSTANCE hInstDLL)
Definition: winmm.c:58
UINT WINAPI waveInAddBuffer(HWAVEIN hWaveIn, WAVEHDR *lpWaveInHdr, UINT uSize)
Definition: winmm.c:2717
UINT WINAPI waveOutGetPlaybackRate(HWAVEOUT hWaveOut, LPDWORD lpdw)
Definition: winmm.c:2457
static BOOL MMSYSTEM_MidiStream_MessageHandler(WINE_MIDIStream *lpMidiStrm, LPWINE_MIDI lpwm, LPMSG msg)
Definition: winmm.c:1513
UINT WINAPI mixerGetDevCapsW(UINT_PTR uDeviceID, LPMIXERCAPSW lpCaps, UINT uSize)
Definition: winmm.c:314
UINT WINAPI midiOutGetErrorTextW(UINT uError, LPWSTR lpText, UINT uSize)
Definition: winmm.c:888
UINT WINAPI midiOutMessage(HMIDIOUT hMidiOut, UINT uMessage, DWORD_PTR dwParam1, DWORD_PTR dwParam2)
Definition: winmm.c:1153
MMRESULT WINAPI midiConnect(HMIDI hMidi, HMIDIOUT hmo, LPVOID pReserved)
Definition: winmm.c:1438
UINT WINAPI waveInPrepareHeader(HWAVEIN hWaveIn, WAVEHDR *lpWaveInHdr, UINT uSize)
Definition: winmm.c:2653
UINT WINAPI midiInGetNumDevs(void)
Definition: winmm.c:1184
UINT WINAPI waveOutSetPitch(HWAVEOUT hWaveOut, DWORD dw)
Definition: winmm.c:2443
UINT WINAPI waveInStop(HWAVEIN hWaveIn)
Definition: winmm.c:2764
static void CALLBACK MIXER_WCallback(HMIXEROBJ hmx, UINT uMsg, DWORD_PTR dwInstance, DWORD_PTR dwParam, DWORD_PTR param2)
Definition: winmm.c:326
UINT WINAPI midiInGetDevCapsA(UINT_PTR uDeviceID, LPMIDIINCAPSA lpCaps, UINT uSize)
Definition: winmm.c:1209
UINT WINAPI waveOutGetErrorTextA(UINT uError, LPSTR lpText, UINT uSize)
Definition: winmm.c:2198
UINT WINAPI midiInGetID(HMIDIIN hMidiIn, UINT *lpuDeviceID)
Definition: winmm.c:1397
UINT WINAPI waveOutSetVolume(HWAVEOUT hWaveOut, DWORD dw)
Definition: winmm.c:2505
UINT WINAPI midiOutLongMsg(HMIDIOUT hMidiOut, MIDIHDR *lpMidiOutHdr, UINT uSize)
Definition: winmm.c:1054
UINT WINAPI mixerGetControlDetailsW(HMIXEROBJ hmix, LPMIXERCONTROLDETAILS lpmcdW, DWORD fdwDetails)
Definition: winmm.c:423
static UINT WAVE_Open(HANDLE *lphndl, UINT uDeviceID, UINT uType, LPCWAVEFORMATEX lpFormat, DWORD_PTR dwCallback, DWORD_PTR dwInstance, DWORD dwFlags)
Definition: winmm.c:2052
UINT WINAPI midiOutSetVolume(HMIDIOUT hMidiOut, DWORD dwVolume)
Definition: winmm.c:1100
UINT WINAPI auxGetNumDevs(void)
Definition: winmm.c:715
static UINT MIXER_GetDev(HMIXEROBJ hmix, DWORD dwFlags, LPWINE_MIXER *lplpwm)
Definition: winmm.c:226
UINT WINAPI midiOutUnprepareHeader(HMIDIOUT hMidiOut, MIDIHDR *lpMidiOutHdr, UINT uSize)
Definition: winmm.c:1016
UINT WINAPI mixerGetLineInfoW(HMIXEROBJ hmix, LPMIXERLINEW lpmliW, DWORD fdwInfo)
Definition: winmm.c:592
UINT WINAPI waveInUnprepareHeader(HWAVEIN hWaveIn, WAVEHDR *lpWaveInHdr, UINT uSize)
Definition: winmm.c:2684
UINT WINAPI auxGetDevCapsA(UINT_PTR uDeviceID, LPAUXCAPSA lpCaps, UINT uSize)
Definition: winmm.c:739
UINT WINAPI midiOutGetNumDevs(void)
Definition: winmm.c:806
UINT WINAPI mixerGetNumDevs(void)
Definition: winmm.c:280
static LPWINE_MIDI MIDI_OutAlloc(HMIDIOUT *lphMidiOut, DWORD_PTR *lpdwCallback, DWORD_PTR *lpdwInstance, LPDWORD lpdwFlags, DWORD cIDs, MIDIOPENSTRMID *lpIDs)
Definition: winmm.c:909
DWORD WINAPI mixerMessage(HMIXER hmix, UINT uMsg, DWORD_PTR dwParam1, DWORD_PTR dwParam2)
Definition: winmm.c:699
UINT WINAPI waveOutGetNumDevs(void)
Definition: winmm.c:2137
UINT WINAPI midiOutGetErrorTextA(UINT uError, LPSTR lpText, UINT uSize)
Definition: winmm.c:863
UINT WINAPI midiOutGetVolume(HMIDIOUT hMidiOut, DWORD *lpdwVolume)
Definition: winmm.c:1085
UINT WINAPI midiOutCachePatches(HMIDIOUT hMidiOut, UINT uBank, WORD *lpwPatchArray, UINT uFlags)
Definition: winmm.c:1115
UINT WINAPI midiOutClose(HMIDIOUT hMidiOut)
Definition: winmm.c:978
MMRESULT WINAPI midiInOpen(HMIDIIN *lphMidiIn, UINT uDeviceID, DWORD_PTR dwCallback, DWORD_PTR dwInstance, DWORD dwFlags)
Definition: winmm.c:1234
UINT WINAPI waveOutGetPosition(HWAVEOUT hWaveOut, LPMMTIME lpTime, UINT uSize)
Definition: winmm.c:2413
UINT WINAPI mixerGetDevCapsA(UINT_PTR uDeviceID, LPMIXERCAPSA lpCaps, UINT uSize)
Definition: winmm.c:288
MMRESULT WINMM_CheckCallback(DWORD_PTR dwCallback, DWORD fdwOpen, BOOL mixer)
Definition: winmm.c:193
UINT WINAPI waveInGetID(HWAVEIN hWaveIn, UINT *lpuDeviceID)
Definition: winmm.c:2795
UINT WINAPI midiInStart(HMIDIIN hMidiIn)
Definition: winmm.c:1352
UINT WINAPI mixerOpen(LPHMIXER lphMix, UINT uDeviceID, DWORD_PTR dwCallback, DWORD_PTR dwInstance, DWORD fdwOpen)
Definition: winmm.c:339
HINSTANCE hWinMM32Instance
Definition: winmm.c:50
UINT WINAPI waveInReset(HWAVEIN hWaveIn)
Definition: winmm.c:2734
static BOOL MMSYSTEM_MidiStream_PostMessage(WINE_MIDIStream *lpMidiStrm, WORD msg, DWORD pmt1, DWORD pmt2)
Definition: winmm.c:1757
UINT WINAPI waveOutBreakLoop(HWAVEOUT hWaveOut)
Definition: winmm.c:2357
UINT WINAPI midiOutGetID(HMIDIOUT hMidiOut, UINT *lpuDeviceID)
Definition: winmm.c:1136
UINT WINAPI waveOutWrite(HWAVEOUT hWaveOut, LPWAVEHDR lpWaveOutHdr, UINT uSize)
Definition: winmm.c:2341
UINT WINAPI mixerGetControlDetailsA(HMIXEROBJ hmix, LPMIXERCONTROLDETAILS lpmcdA, DWORD fdwDetails)
Definition: winmm.c:444
UINT WINAPI waveOutUnprepareHeader(HWAVEOUT hWaveOut, LPWAVEHDR lpWaveOutHdr, UINT uSize)
Definition: winmm.c:2307
MMRESULT WINAPI waveOutOpen(LPHWAVEOUT lphWaveOut, UINT uDeviceID, LPCWAVEFORMATEX lpFormat, DWORD_PTR dwCallback, DWORD_PTR dwInstance, DWORD dwFlags)
Definition: winmm.c:2246
UINT WINAPI waveOutRestart(HWAVEOUT hWaveOut)
Definition: winmm.c:2399
UINT WINAPI midiOutShortMsg(HMIDIOUT hMidiOut, DWORD dwMsg)
Definition: winmm.c:1039
UINT WINAPI waveOutGetDevCapsW(UINT_PTR uDeviceID, LPWAVEOUTCAPSW lpCaps, UINT uSize)
Definition: winmm.c:2173
static DWORD MMSYSTEM_MidiStream_Convert(WINE_MIDIStream *lpMidiStrm, DWORD pulse)
Definition: winmm.c:1492
MMRESULT WINAPI midiOutOpen(LPHMIDIOUT lphMidiOut, UINT uDeviceID, DWORD_PTR dwCallback, DWORD_PTR dwInstance, DWORD dwFlags)
Definition: winmm.c:939
BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID fImpLoad)
Definition: winmm.c:156
static DWORD CALLBACK MMSYSTEM_MidiStream_Player(LPVOID pmt)
Definition: winmm.c:1632
UINT WINAPI waveOutGetPitch(HWAVEOUT hWaveOut, LPDWORD lpdw)
Definition: winmm.c:2429
UINT WINAPI auxSetVolume(UINT uDeviceID, DWORD dwVolume)
Definition: winmm.c:779
UINT WINAPI mixerGetLineInfoA(HMIXEROBJ hmix, LPMIXERLINEA lpmliA, DWORD fdwInfo)
Definition: winmm.c:612
UINT WINAPI mixerGetID(HMIXEROBJ hmix, LPUINT lpid, DWORD fdwID)
Definition: winmm.c:404
BOOL WINAPI mmTaskSignal(DWORD tid)
Definition: winmm.c:2899
#define WINE_MSM_STOP
Definition: winmm.c:1468
MMRESULT WINAPI waveInOpen(HWAVEIN *lphWaveIn, UINT uDeviceID, LPCWAVEFORMATEX lpFormat, DWORD_PTR dwCallback, DWORD_PTR dwInstance, DWORD dwFlags)
Definition: winmm.c:2623
MMRESULT WINAPI midiStreamOut(HMIDISTRM hMidiStrm, LPMIDIHDR lpMidiHdr, UINT cbMidiHdr)
Definition: winmm.c:1866
UINT WINAPI auxGetDevCapsW(UINT_PTR uDeviceID, LPAUXCAPSW lpCaps, UINT uSize)
Definition: winmm.c:723
UINT WINAPI mixerSetControlDetails(HMIXEROBJ hmix, LPMIXERCONTROLDETAILS lpmcd, DWORD fdwDetails)
Definition: winmm.c:681
UINT WINAPI waveOutGetID(HWAVEOUT hWaveOut, UINT *lpuDeviceID)
Definition: winmm.c:2520
BOOL WINMM_CheckForMMSystem(void)
Definition: winmm.c:86
CRITICAL_SECTION WINMM_cs
Definition: winmm.c:53
#define ERR_TO_STR(dev)
MMRESULT WINAPI midiStreamClose(HMIDISTRM hMidiStrm)
Definition: winmm.c:1775
UINT WINAPI waveInGetNumDevs(void)
Definition: winmm.c:2565
UINT WINAPI auxOutMessage(UINT uDeviceID, UINT uMessage, DWORD_PTR dw1, DWORD_PTR dw2)
Definition: winmm.c:793
const char * WINMM_ErrorToString(MMRESULT error)
Definition: winmm.c:110
UINT WINAPI midiOutGetDevCapsW(UINT_PTR uDeviceID, LPMIDIOUTCAPSW lpCaps, UINT uSize)
Definition: winmm.c:814
UINT WINAPI waveInClose(HWAVEIN hWaveIn)
Definition: winmm.c:2634
MMRESULT WINAPI midiStreamStop(HMIDISTRM hMidiStrm)
Definition: winmm.c:2035
UINT WINAPI waveOutPrepareHeader(HWAVEOUT hWaveOut, WAVEHDR *lpWaveOutHdr, UINT uSize)
Definition: winmm.c:2277
MMRESULT WINAPI midiStreamPause(HMIDISTRM hMidiStrm)
Definition: winmm.c:1904
UINT WINAPI waveOutSetPlaybackRate(HWAVEOUT hWaveOut, DWORD dw)
Definition: winmm.c:2471
UINT WINAPI midiOutPrepareHeader(HMIDIOUT hMidiOut, MIDIHDR *lpMidiOutHdr, UINT uSize)
Definition: winmm.c:997
UINT WINAPI midiInClose(HMIDIIN hMidiIn)
Definition: winmm.c:1276
UINT WINAPI midiOutCacheDrumPatches(HMIDIOUT hMidiOut, UINT uPatch, WORD *lpwKeyArray, UINT uFlags)
Definition: winmm.c:1126
MMRESULT WINAPI midiStreamOpen(HMIDISTRM *lphMidiStrm, LPUINT lpuDeviceID, DWORD cMidi, DWORD_PTR dwCallback, DWORD_PTR dwInstance, DWORD fdwOpen)
Definition: winmm.c:1795
UINT WINAPI waveInStart(HWAVEIN hWaveIn)
Definition: winmm.c:2749
MMRESULT WINAPI midiDisconnect(HMIDI hMidi, HMIDIOUT hmo, LPVOID pReserved)
Definition: winmm.c:1447
#define WINE_MSM_HEADER
Definition: winmm.c:1467
UINT WINAPI midiInGetDevCapsW(UINT_PTR uDeviceID, LPMIDIINCAPSW lpCaps, UINT uSize)
Definition: winmm.c:1192
UINT WINAPI waveOutPause(HWAVEOUT hWaveOut)
Definition: winmm.c:2371
UINT WINAPI midiInMessage(HMIDIIN hMidiIn, UINT uMessage, DWORD_PTR dwParam1, DWORD_PTR dwParam2)
Definition: winmm.c:1416
UINT WINAPI waveInGetDevCapsA(UINT_PTR uDeviceID, LPWAVEINCAPSA lpCaps, UINT uSize)
Definition: winmm.c:2597
UINT WINAPI waveInMessage(HWAVEIN hWaveIn, UINT uMessage, DWORD_PTR dwParam1, DWORD_PTR dwParam2)
Definition: winmm.c:2813
UINT WINAPI midiInAddBuffer(HMIDIIN hMidiIn, MIDIHDR *lpMidiInHdr, UINT uSize)
Definition: winmm.c:1336
UINT WINAPI midiOutGetDevCapsA(UINT_PTR uDeviceID, LPMIDIOUTCAPSA lpCaps, UINT uSize)
Definition: winmm.c:832
UINT WINAPI waveOutMessage(HWAVEOUT hWaveOut, UINT uMessage, DWORD_PTR dwParam1, DWORD_PTR dwParam2)
Definition: winmm.c:2538
UINT WINAPI waveOutGetVolume(HWAVEOUT hWaveOut, LPDWORD lpdw)
Definition: winmm.c:2485
UINT WINAPI waveOutClose(HWAVEOUT hWaveOut)
Definition: winmm.c:2257
VOID WINAPI mmTaskBlock(DWORD tid)
Definition: winmm.c:2885
UINT WINAPI midiInPrepareHeader(HMIDIIN hMidiIn, MIDIHDR *lpMidiInHdr, UINT uSize)
Definition: winmm.c:1294
UINT WINAPI waveInGetDevCapsW(UINT_PTR uDeviceID, LPWAVEINCAPSW lpCaps, UINT uSize)
Definition: winmm.c:2573
static BOOL MMSYSTEM_GetMidiStream(HMIDISTRM hMidiStrm, WINE_MIDIStream **lpMidiStrm, WINE_MIDI **lplpwm)
Definition: winmm.c:1473
LRESULT WINAPI DispatchMessageA(_In_ const MSG *)
BOOL WINAPI IsWindow(_In_opt_ HWND)
#define WM_QUIT
Definition: winuser.h:1623
BOOL WINAPI PostMessageW(_In_opt_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
int WINAPI LoadStringW(_In_opt_ HINSTANCE hInstance, _In_ UINT uID, _Out_writes_to_(cchBufferMax, return+1) LPWSTR lpBuffer, _In_ int cchBufferMax)
#define QS_ALLINPUT
Definition: winuser.h:903
DWORD WINAPI MsgWaitForMultipleObjects(_In_ DWORD nCount, _In_reads_opt_(nCount) CONST HANDLE *pHandles, _In_ BOOL fWaitAll, _In_ DWORD dwMilliseconds, _In_ DWORD dwWakeMask)
BOOL WINAPI PostThreadMessageW(_In_ DWORD, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
#define PM_REMOVE
Definition: winuser.h:1196
BOOL WINAPI PeekMessageA(_Out_ LPMSG, _In_opt_ HWND, _In_ UINT, _In_ UINT, _In_ UINT)
#define WM_USER
Definition: winuser.h:1895
BOOL WINAPI PostThreadMessageA(_In_ DWORD, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
BOOL WINAPI GetMessageA(_Out_ LPMSG, _In_opt_ HWND, _In_ UINT, _In_ UINT)
const char * LPCSTR
Definition: xmlstorage.h:183
char * LPSTR
Definition: xmlstorage.h:182
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * LPWSTR
Definition: xmlstorage.h:184
unsigned char BYTE
Definition: xxhash.c:193