1 /* -*- tab-width: 8; c-basic-offset: 4 -*- */
6 * Copyright 1998 Patrik Stridvall
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
34 #include "wine/debug.h"
36 WINE_DEFAULT_DEBUG_CHANNEL(msacm);
38 /***********************************************************************
39 * acmFilterChooseA (MSACM32.@)
41 MMRESULT WINAPI acmFilterChooseA(PACMFILTERCHOOSEA pafltrc)
43 FIXME("(%p): stub\n", pafltrc);
44 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
45 return MMSYSERR_ERROR;
48 /***********************************************************************
49 * acmFilterChooseW (MSACM32.@)
51 MMRESULT WINAPI acmFilterChooseW(PACMFILTERCHOOSEW pafltrc)
53 FIXME("(%p): stub\n", pafltrc);
54 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
55 return MMSYSERR_ERROR;
58 /***********************************************************************
59 * acmFilterDetailsA (MSACM32.@)
61 MMRESULT WINAPI acmFilterDetailsA(HACMDRIVER had, PACMFILTERDETAILSA pafd,
64 ACMFILTERDETAILSW afdw;
67 memset(&afdw, 0, sizeof(afdw));
68 afdw.cbStruct = sizeof(afdw);
69 afdw.dwFilterIndex = pafd->dwFilterIndex;
70 afdw.dwFilterTag = pafd->dwFilterTag;
71 afdw.pwfltr = pafd->pwfltr;
72 afdw.cbwfltr = pafd->cbwfltr;
74 mmr = acmFilterDetailsW(had, &afdw, fdwDetails);
75 if (mmr == MMSYSERR_NOERROR) {
76 pafd->dwFilterTag = afdw.dwFilterTag;
77 pafd->fdwSupport = afdw.fdwSupport;
78 WideCharToMultiByte( CP_ACP, 0, afdw.szFilter, -1, pafd->szFilter,
79 sizeof(pafd->szFilter), NULL, NULL );
84 /***********************************************************************
85 * acmFilterDetailsW (MSACM32.@)
87 MMRESULT WINAPI acmFilterDetailsW(HACMDRIVER had, PACMFILTERDETAILSW pafd,
91 ACMFILTERTAGDETAILSA aftd;
93 TRACE("(%p, %p, %ld)\n", had, pafd, fdwDetails);
95 memset(&aftd, 0, sizeof(aftd));
96 aftd.cbStruct = sizeof(aftd);
98 if (pafd->cbStruct < sizeof(*pafd)) return MMSYSERR_INVALPARAM;
100 switch (fdwDetails) {
101 case ACM_FILTERDETAILSF_FILTER:
102 if (pafd->dwFilterTag != pafd->pwfltr->dwFilterTag) {
103 mmr = MMSYSERR_INVALPARAM;
107 PWINE_ACMDRIVERID padid;
109 mmr = ACMERR_NOTPOSSIBLE;
110 for (padid = MSACM_pFirstACMDriverID; padid; padid = padid->pNextACMDriverID) {
111 /* should check for codec only */
112 if (!(padid->fdwSupport & ACMDRIVERDETAILS_SUPPORTF_DISABLED) &&
113 acmDriverOpen(&had, (HACMDRIVERID)padid, 0) == 0) {
114 mmr = MSACM_Message(had, ACMDM_FILTER_DETAILS,
115 (LPARAM)pafd, (LPARAM)fdwDetails);
116 acmDriverClose(had, 0);
117 if (mmr == MMSYSERR_NOERROR) break;
121 mmr = MSACM_Message(had, ACMDM_FILTER_DETAILS, (LPARAM)pafd, fdwDetails);
124 case ACM_FILTERDETAILSF_INDEX:
125 /* should check pafd->dwFilterIndex < aftd->cStandardFilters */
126 mmr = MSACM_Message(had, ACMDM_FILTER_DETAILS, (LPARAM)pafd, fdwDetails);
129 WARN("Unknown fdwDetails %08lx\n", fdwDetails);
130 mmr = MMSYSERR_INVALFLAG;
134 TRACE("=> %d\n", mmr);
138 struct MSACM_FilterEnumWtoA_Instance {
139 PACMFILTERDETAILSA pafda;
141 ACMFILTERENUMCBA fnCallback;
144 static BOOL CALLBACK MSACM_FilterEnumCallbackWtoA(HACMDRIVERID hadid,
145 PACMFILTERDETAILSW pafdw,
149 struct MSACM_FilterEnumWtoA_Instance* pafei;
151 pafei = (struct MSACM_FilterEnumWtoA_Instance*)dwInstance;
153 pafei->pafda->dwFilterIndex = pafdw->dwFilterIndex;
154 pafei->pafda->dwFilterTag = pafdw->dwFilterTag;
155 pafei->pafda->fdwSupport = pafdw->fdwSupport;
156 WideCharToMultiByte( CP_ACP, 0, pafdw->szFilter, -1, pafei->pafda->szFilter,
157 sizeof(pafei->pafda->szFilter), NULL, NULL );
159 return (pafei->fnCallback)(hadid, pafei->pafda,
160 pafei->dwInstance, fdwSupport);
163 /***********************************************************************
164 * acmFilterEnumA (MSACM32.@)
166 MMRESULT WINAPI acmFilterEnumA(HACMDRIVER had, PACMFILTERDETAILSA pafda,
167 ACMFILTERENUMCBA fnCallback, DWORD dwInstance,
170 ACMFILTERDETAILSW afdw;
171 struct MSACM_FilterEnumWtoA_Instance afei;
173 memset(&afdw, 0, sizeof(afdw));
174 afdw.cbStruct = sizeof(afdw);
175 afdw.dwFilterIndex = pafda->dwFilterIndex;
176 afdw.dwFilterTag = pafda->dwFilterTag;
177 afdw.pwfltr = pafda->pwfltr;
178 afdw.cbwfltr = pafda->cbwfltr;
181 afei.dwInstance = dwInstance;
182 afei.fnCallback = fnCallback;
184 return acmFilterEnumW(had, &afdw, MSACM_FilterEnumCallbackWtoA,
185 (DWORD)&afei, fdwEnum);
188 static BOOL MSACM_FilterEnumHelper(PWINE_ACMDRIVERID padid, HACMDRIVER had,
189 PACMFILTERDETAILSW pafd,
190 ACMFILTERENUMCBW fnCallback, DWORD dwInstance,
193 ACMFILTERTAGDETAILSW aftd;
196 for (i = 0; i < padid->cFilterTags; i++) {
197 memset(&aftd, 0, sizeof(aftd));
198 aftd.cbStruct = sizeof(aftd);
199 aftd.dwFilterTagIndex = i;
200 if (acmFilterTagDetailsW(had, &aftd, ACM_FILTERTAGDETAILSF_INDEX) != MMSYSERR_NOERROR)
203 if ((fdwEnum & ACM_FILTERENUMF_DWFILTERTAG) &&
204 aftd.dwFilterTag != pafd->pwfltr->dwFilterTag)
207 for (j = 0; j < aftd.cStandardFilters; j++) {
208 pafd->dwFilterIndex = j;
209 pafd->dwFilterTag = aftd.dwFilterTag;
210 if (acmFilterDetailsW(had, pafd, ACM_FILTERDETAILSF_INDEX) != MMSYSERR_NOERROR)
213 if (!(fnCallback)((HACMDRIVERID)padid, pafd, dwInstance, padid->fdwSupport))
220 /***********************************************************************
221 * acmFilterEnumW (MSACM32.@)
223 MMRESULT WINAPI acmFilterEnumW(HACMDRIVER had, PACMFILTERDETAILSW pafd,
224 ACMFILTERENUMCBW fnCallback, DWORD dwInstance,
227 PWINE_ACMDRIVERID padid;
230 TRACE("(%p, %p, %p, %ld, %ld)\n",
231 had, pafd, fnCallback, dwInstance, fdwEnum);
233 if (pafd->cbStruct < sizeof(*pafd)) return MMSYSERR_INVALPARAM;
235 if (fdwEnum & ~(ACM_FILTERENUMF_DWFILTERTAG))
236 FIXME("Unsupported fdwEnum values\n");
241 if (acmDriverID((HACMOBJ)had, &hadid, 0) != MMSYSERR_NOERROR)
242 return MMSYSERR_INVALHANDLE;
243 MSACM_FilterEnumHelper(MSACM_GetDriverID(hadid), had, pafd,
244 fnCallback, dwInstance, fdwEnum);
245 return MMSYSERR_NOERROR;
247 for (padid = MSACM_pFirstACMDriverID; padid; padid = padid->pNextACMDriverID) {
248 /* should check for codec only */
249 if ((padid->fdwSupport & ACMDRIVERDETAILS_SUPPORTF_DISABLED) ||
250 acmDriverOpen(&had, (HACMDRIVERID)padid, 0) != MMSYSERR_NOERROR)
252 ret = MSACM_FilterEnumHelper(padid, had, pafd,
253 fnCallback, dwInstance, fdwEnum);
254 acmDriverClose(had, 0);
257 return MMSYSERR_NOERROR;
260 /***********************************************************************
261 * acmFilterTagDetailsA (MSACM32.@)
263 MMRESULT WINAPI acmFilterTagDetailsA(HACMDRIVER had, PACMFILTERTAGDETAILSA paftda,
266 ACMFILTERTAGDETAILSW aftdw;
269 memset(&aftdw, 0, sizeof(aftdw));
270 aftdw.cbStruct = sizeof(aftdw);
271 aftdw.dwFilterTagIndex = paftda->dwFilterTagIndex;
272 aftdw.dwFilterTag = paftda->dwFilterTag;
274 mmr = acmFilterTagDetailsW(had, &aftdw, fdwDetails);
275 if (mmr == MMSYSERR_NOERROR) {
276 paftda->dwFilterTag = aftdw.dwFilterTag;
277 paftda->dwFilterTagIndex = aftdw.dwFilterTagIndex;
278 paftda->cbFilterSize = aftdw.cbFilterSize;
279 paftda->fdwSupport = aftdw.fdwSupport;
280 paftda->cStandardFilters = aftdw.cStandardFilters;
281 WideCharToMultiByte( CP_ACP, 0, aftdw.szFilterTag, -1, paftda->szFilterTag,
282 sizeof(paftda->szFilterTag), NULL, NULL );
287 /***********************************************************************
288 * acmFilterTagDetailsW (MSACM32.@)
290 MMRESULT WINAPI acmFilterTagDetailsW(HACMDRIVER had, PACMFILTERTAGDETAILSW paftd,
293 PWINE_ACMDRIVERID padid;
296 TRACE("(%p, %p, %ld)\n", had, paftd, fdwDetails);
298 if (fdwDetails & ~(ACM_FILTERTAGDETAILSF_FILTERTAG|ACM_FILTERTAGDETAILSF_INDEX|
299 ACM_FILTERTAGDETAILSF_LARGESTSIZE))
300 return MMSYSERR_INVALFLAG;
302 switch (fdwDetails) {
303 case ACM_FILTERTAGDETAILSF_FILTERTAG:
305 mmr = ACMERR_NOTPOSSIBLE;
306 for (padid = MSACM_pFirstACMDriverID; padid; padid = padid->pNextACMDriverID) {
307 /* should check for codec only */
308 if (!(padid->fdwSupport & ACMDRIVERDETAILS_SUPPORTF_DISABLED) &&
309 acmDriverOpen(&had, (HACMDRIVERID)padid, 0) == 0) {
310 mmr = MSACM_Message(had, ACMDM_FILTERTAG_DETAILS, (LPARAM)paftd, fdwDetails);
311 acmDriverClose(had, 0);
312 if (mmr == MMSYSERR_NOERROR) break;
316 mmr = MSACM_Message(had, ACMDM_FILTERTAG_DETAILS, (LPARAM)paftd, fdwDetails);
320 case ACM_FILTERTAGDETAILSF_INDEX:
321 /* FIXME should check paftd->dwFilterTagIndex < add.cFilterTags */
322 mmr = MSACM_Message(had, ACMDM_FILTERTAG_DETAILS, (LPARAM)paftd, fdwDetails);
325 case ACM_FILTERTAGDETAILSF_LARGESTSIZE:
327 ACMFILTERTAGDETAILSW tmp;
328 DWORD ft = paftd->dwFilterTag;
330 mmr = ACMERR_NOTPOSSIBLE;
331 for (padid = MSACM_pFirstACMDriverID; padid; padid = padid->pNextACMDriverID) {
332 /* should check for codec only */
333 if (!(padid->fdwSupport & ACMDRIVERDETAILS_SUPPORTF_DISABLED) &&
334 acmDriverOpen(&had, (HACMDRIVERID)padid, 0) == 0) {
336 memset(&tmp, 0, sizeof(tmp));
337 tmp.cbStruct = sizeof(tmp);
338 tmp.dwFilterTag = ft;
340 if (MSACM_Message(had, ACMDM_FILTERTAG_DETAILS,
341 (LPARAM)&tmp, fdwDetails) == MMSYSERR_NOERROR) {
342 if (mmr == ACMERR_NOTPOSSIBLE ||
343 paftd->cbFilterSize < tmp.cbFilterSize) {
345 mmr = MMSYSERR_NOERROR;
348 acmDriverClose(had, 0);
352 mmr = MSACM_Message(had, ACMDM_FILTERTAG_DETAILS, (LPARAM)paftd, fdwDetails);
357 WARN("Unsupported fdwDetails=%08lx\n", fdwDetails);
358 mmr = MMSYSERR_ERROR;
361 if (mmr == MMSYSERR_NOERROR &&
362 paftd->dwFilterTag == WAVE_FORMAT_PCM && paftd->szFilterTag[0] == 0)
363 MultiByteToWideChar( CP_ACP, 0, "PCM", -1, paftd->szFilterTag,
364 sizeof(paftd->szFilterTag)/sizeof(WCHAR) );
369 struct MSACM_FilterTagEnumWtoA_Instance {
370 PACMFILTERTAGDETAILSA paftda;
372 ACMFILTERTAGENUMCBA fnCallback;
375 static BOOL CALLBACK MSACM_FilterTagEnumCallbackWtoA(HACMDRIVERID hadid,
376 PACMFILTERTAGDETAILSW paftdw,
380 struct MSACM_FilterTagEnumWtoA_Instance* paftei;
382 paftei = (struct MSACM_FilterTagEnumWtoA_Instance*)dwInstance;
384 paftei->paftda->dwFilterTagIndex = paftdw->dwFilterTagIndex;
385 paftei->paftda->dwFilterTag = paftdw->dwFilterTag;
386 paftei->paftda->cbFilterSize = paftdw->cbFilterSize;
387 paftei->paftda->fdwSupport = paftdw->fdwSupport;
388 paftei->paftda->cStandardFilters = paftdw->cStandardFilters;
389 WideCharToMultiByte( CP_ACP, 0, paftdw->szFilterTag, -1, paftei->paftda->szFilterTag,
390 sizeof(paftei->paftda->szFilterTag), NULL, NULL );
392 return (paftei->fnCallback)(hadid, paftei->paftda,
393 paftei->dwInstance, fdwSupport);
396 /***********************************************************************
397 * acmFilterTagEnumA (MSACM32.@)
399 MMRESULT WINAPI acmFilterTagEnumA(HACMDRIVER had, PACMFILTERTAGDETAILSA paftda,
400 ACMFILTERTAGENUMCBA fnCallback, DWORD dwInstance,
403 ACMFILTERTAGDETAILSW aftdw;
404 struct MSACM_FilterTagEnumWtoA_Instance aftei;
406 memset(&aftdw, 0, sizeof(aftdw));
407 aftdw.cbStruct = sizeof(aftdw);
408 aftdw.dwFilterTagIndex = paftda->dwFilterTagIndex;
409 aftdw.dwFilterTag = paftda->dwFilterTag;
411 aftei.paftda = paftda;
412 aftei.dwInstance = dwInstance;
413 aftei.fnCallback = fnCallback;
415 return acmFilterTagEnumW(had, &aftdw, MSACM_FilterTagEnumCallbackWtoA,
416 (DWORD)&aftei, fdwEnum);
419 /***********************************************************************
420 * acmFilterTagEnumW (MSACM32.@)
422 MMRESULT WINAPI acmFilterTagEnumW(HACMDRIVER had, PACMFILTERTAGDETAILSW paftd,
423 ACMFILTERTAGENUMCBW fnCallback, DWORD dwInstance,
426 PWINE_ACMDRIVERID padid;
429 TRACE("(%p, %p, %p, %ld, %ld)\n",
430 had, paftd, fnCallback, dwInstance, fdwEnum);
432 if (paftd->cbStruct < sizeof(*paftd)) return MMSYSERR_INVALPARAM;
434 if (had) FIXME("had != NULL, not supported\n");
436 for (padid = MSACM_pFirstACMDriverID; padid; padid = padid->pNextACMDriverID) {
437 /* should check for codec only */
438 if (!(padid->fdwSupport & ACMDRIVERDETAILS_SUPPORTF_DISABLED) &&
439 acmDriverOpen(&had, (HACMDRIVERID)padid, 0) == MMSYSERR_NOERROR) {
441 for (i = 0; i < padid->cFilterTags; i++) {
442 paftd->dwFilterTagIndex = i;
443 if (acmFilterTagDetailsW(had, paftd, ACM_FILTERTAGDETAILSF_INDEX) == MMSYSERR_NOERROR) {
444 if (!(fnCallback)((HACMDRIVERID)padid, paftd, dwInstance, padid->fdwSupport)) {
451 acmDriverClose(had, 0);
453 return MMSYSERR_NOERROR;