Release 20030408.
[wine/gsoc-2012-control.git] / dlls / msacm / filter.c
blob638912503d733454d5a1ac59eb0985faf30d9345
1 /* -*- tab-width: 8; c-basic-offset: 4 -*- */
3 /*
4 * MSACM32 library
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
23 #include <string.h>
24 #include "winbase.h"
25 #include "winnls.h"
26 #include "winerror.h"
27 #include "mmsystem.h"
28 #include "msacm.h"
29 #include "msacmdrv.h"
30 #include "wineacm.h"
31 #include "wine/debug.h"
33 WINE_DEFAULT_DEBUG_CHANNEL(msacm);
35 /***********************************************************************
36 * acmFilterChooseA (MSACM32.@)
38 MMRESULT WINAPI acmFilterChooseA(PACMFILTERCHOOSEA pafltrc)
40 FIXME("(%p): stub\n", pafltrc);
41 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
42 return MMSYSERR_ERROR;
45 /***********************************************************************
46 * acmFilterChooseW (MSACM32.@)
48 MMRESULT WINAPI acmFilterChooseW(PACMFILTERCHOOSEW pafltrc)
50 FIXME("(%p): stub\n", pafltrc);
51 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
52 return MMSYSERR_ERROR;
55 /***********************************************************************
56 * acmFilterDetailsA (MSACM32.@)
58 MMRESULT WINAPI acmFilterDetailsA(HACMDRIVER had, PACMFILTERDETAILSA pafd,
59 DWORD fdwDetails)
61 ACMFILTERDETAILSW afdw;
62 MMRESULT mmr;
64 memset(&afdw, 0, sizeof(afdw));
65 afdw.cbStruct = sizeof(afdw);
66 afdw.dwFilterIndex = pafd->dwFilterIndex;
67 afdw.dwFilterTag = pafd->dwFilterTag;
68 afdw.pwfltr = pafd->pwfltr;
69 afdw.cbwfltr = pafd->cbwfltr;
71 mmr = acmFilterDetailsW(had, &afdw, fdwDetails);
72 if (mmr == MMSYSERR_NOERROR) {
73 pafd->dwFilterTag = afdw.dwFilterTag;
74 pafd->fdwSupport = afdw.fdwSupport;
75 WideCharToMultiByte( CP_ACP, 0, afdw.szFilter, -1, pafd->szFilter,
76 sizeof(pafd->szFilter), NULL, NULL );
78 return mmr;
81 /***********************************************************************
82 * acmFilterDetailsW (MSACM32.@)
84 MMRESULT WINAPI acmFilterDetailsW(HACMDRIVER had, PACMFILTERDETAILSW pafd,
85 DWORD fdwDetails)
87 MMRESULT mmr;
88 ACMFILTERTAGDETAILSA aftd;
90 TRACE("(%p, %p, %ld)\n", had, pafd, fdwDetails);
92 memset(&aftd, 0, sizeof(aftd));
93 aftd.cbStruct = sizeof(aftd);
95 if (pafd->cbStruct < sizeof(*pafd)) return MMSYSERR_INVALPARAM;
97 switch (fdwDetails) {
98 case ACM_FILTERDETAILSF_FILTER:
99 if (pafd->dwFilterTag != pafd->pwfltr->dwFilterTag) {
100 mmr = MMSYSERR_INVALPARAM;
101 break;
103 if (had == NULL) {
104 PWINE_ACMDRIVERID padid;
106 mmr = ACMERR_NOTPOSSIBLE;
107 for (padid = MSACM_pFirstACMDriverID; padid; padid = padid->pNextACMDriverID) {
108 /* should check for codec only */
109 if (!(padid->fdwSupport & ACMDRIVERDETAILS_SUPPORTF_DISABLED) &&
110 acmDriverOpen(&had, (HACMDRIVERID)padid, 0) == 0) {
111 mmr = MSACM_Message(had, ACMDM_FILTER_DETAILS,
112 (LPARAM)pafd, (LPARAM)fdwDetails);
113 acmDriverClose(had, 0);
114 if (mmr == MMSYSERR_NOERROR) break;
117 } else {
118 mmr = MSACM_Message(had, ACMDM_FILTER_DETAILS, (LPARAM)pafd, fdwDetails);
120 break;
121 case ACM_FILTERDETAILSF_INDEX:
122 /* should check pafd->dwFilterIndex < aftd->cStandardFilters */
123 mmr = MSACM_Message(had, ACMDM_FILTER_DETAILS, (LPARAM)pafd, fdwDetails);
124 break;
125 default:
126 WARN("Unknown fdwDetails %08lx\n", fdwDetails);
127 mmr = MMSYSERR_INVALFLAG;
128 break;
131 TRACE("=> %d\n", mmr);
132 return mmr;
135 struct MSACM_FilterEnumWtoA_Instance {
136 PACMFILTERDETAILSA pafda;
137 DWORD dwInstance;
138 ACMFILTERENUMCBA fnCallback;
141 static BOOL CALLBACK MSACM_FilterEnumCallbackWtoA(HACMDRIVERID hadid,
142 PACMFILTERDETAILSW pafdw,
143 DWORD dwInstance,
144 DWORD fdwSupport)
146 struct MSACM_FilterEnumWtoA_Instance* pafei;
148 pafei = (struct MSACM_FilterEnumWtoA_Instance*)dwInstance;
150 pafei->pafda->dwFilterIndex = pafdw->dwFilterIndex;
151 pafei->pafda->dwFilterTag = pafdw->dwFilterTag;
152 pafei->pafda->fdwSupport = pafdw->fdwSupport;
153 WideCharToMultiByte( CP_ACP, 0, pafdw->szFilter, -1, pafei->pafda->szFilter,
154 sizeof(pafei->pafda->szFilter), NULL, NULL );
156 return (pafei->fnCallback)(hadid, pafei->pafda,
157 pafei->dwInstance, fdwSupport);
160 /***********************************************************************
161 * acmFilterEnumA (MSACM32.@)
163 MMRESULT WINAPI acmFilterEnumA(HACMDRIVER had, PACMFILTERDETAILSA pafda,
164 ACMFILTERENUMCBA fnCallback, DWORD dwInstance,
165 DWORD fdwEnum)
167 ACMFILTERDETAILSW afdw;
168 struct MSACM_FilterEnumWtoA_Instance afei;
170 memset(&afdw, 0, sizeof(afdw));
171 afdw.cbStruct = sizeof(afdw);
172 afdw.dwFilterIndex = pafda->dwFilterIndex;
173 afdw.dwFilterTag = pafda->dwFilterTag;
174 afdw.pwfltr = pafda->pwfltr;
175 afdw.cbwfltr = pafda->cbwfltr;
177 afei.pafda = pafda;
178 afei.dwInstance = dwInstance;
179 afei.fnCallback = fnCallback;
181 return acmFilterEnumW(had, &afdw, MSACM_FilterEnumCallbackWtoA,
182 (DWORD)&afei, fdwEnum);
185 static BOOL MSACM_FilterEnumHelper(PWINE_ACMDRIVERID padid, HACMDRIVER had,
186 PACMFILTERDETAILSW pafd,
187 ACMFILTERENUMCBW fnCallback, DWORD dwInstance,
188 DWORD fdwEnum)
190 ACMFILTERTAGDETAILSW aftd;
191 int i, j;
193 for (i = 0; i < padid->cFilterTags; i++) {
194 memset(&aftd, 0, sizeof(aftd));
195 aftd.cbStruct = sizeof(aftd);
196 aftd.dwFilterTagIndex = i;
197 if (acmFilterTagDetailsW(had, &aftd, ACM_FILTERTAGDETAILSF_INDEX) != MMSYSERR_NOERROR)
198 continue;
200 if ((fdwEnum & ACM_FILTERENUMF_DWFILTERTAG) &&
201 aftd.dwFilterTag != pafd->pwfltr->dwFilterTag)
202 continue;
204 for (j = 0; j < aftd.cStandardFilters; j++) {
205 pafd->dwFilterIndex = j;
206 pafd->dwFilterTag = aftd.dwFilterTag;
207 if (acmFilterDetailsW(had, pafd, ACM_FILTERDETAILSF_INDEX) != MMSYSERR_NOERROR)
208 continue;
210 if (!(fnCallback)((HACMDRIVERID)padid, pafd, dwInstance, padid->fdwSupport))
211 return FALSE;
214 return TRUE;
217 /***********************************************************************
218 * acmFilterEnumW (MSACM32.@)
220 MMRESULT WINAPI acmFilterEnumW(HACMDRIVER had, PACMFILTERDETAILSW pafd,
221 ACMFILTERENUMCBW fnCallback, DWORD dwInstance,
222 DWORD fdwEnum)
224 PWINE_ACMDRIVERID padid;
225 BOOL ret;
227 TRACE("(%p, %p, %p, %ld, %ld)\n",
228 had, pafd, fnCallback, dwInstance, fdwEnum);
230 if (pafd->cbStruct < sizeof(*pafd)) return MMSYSERR_INVALPARAM;
232 if (fdwEnum & ~(ACM_FILTERENUMF_DWFILTERTAG))
233 FIXME("Unsupported fdwEnum values\n");
235 if (had) {
236 HACMDRIVERID hadid;
238 if (acmDriverID((HACMOBJ)had, &hadid, 0) != MMSYSERR_NOERROR)
239 return MMSYSERR_INVALHANDLE;
240 MSACM_FilterEnumHelper(MSACM_GetDriverID(hadid), had, pafd,
241 fnCallback, dwInstance, fdwEnum);
242 return MMSYSERR_NOERROR;
244 for (padid = MSACM_pFirstACMDriverID; padid; padid = padid->pNextACMDriverID) {
245 /* should check for codec only */
246 if ((padid->fdwSupport & ACMDRIVERDETAILS_SUPPORTF_DISABLED) ||
247 acmDriverOpen(&had, (HACMDRIVERID)padid, 0) != MMSYSERR_NOERROR)
248 continue;
249 ret = MSACM_FilterEnumHelper(padid, had, pafd,
250 fnCallback, dwInstance, fdwEnum);
251 acmDriverClose(had, 0);
252 if (!ret) break;
254 return MMSYSERR_NOERROR;
257 /***********************************************************************
258 * acmFilterTagDetailsA (MSACM32.@)
260 MMRESULT WINAPI acmFilterTagDetailsA(HACMDRIVER had, PACMFILTERTAGDETAILSA paftda,
261 DWORD fdwDetails)
263 ACMFILTERTAGDETAILSW aftdw;
264 MMRESULT mmr;
266 memset(&aftdw, 0, sizeof(aftdw));
267 aftdw.cbStruct = sizeof(aftdw);
268 aftdw.dwFilterTagIndex = paftda->dwFilterTagIndex;
269 aftdw.dwFilterTag = paftda->dwFilterTag;
271 mmr = acmFilterTagDetailsW(had, &aftdw, fdwDetails);
272 if (mmr == MMSYSERR_NOERROR) {
273 paftda->dwFilterTag = aftdw.dwFilterTag;
274 paftda->dwFilterTagIndex = aftdw.dwFilterTagIndex;
275 paftda->cbFilterSize = aftdw.cbFilterSize;
276 paftda->fdwSupport = aftdw.fdwSupport;
277 paftda->cStandardFilters = aftdw.cStandardFilters;
278 WideCharToMultiByte( CP_ACP, 0, aftdw.szFilterTag, -1, paftda->szFilterTag,
279 sizeof(paftda->szFilterTag), NULL, NULL );
281 return mmr;
284 /***********************************************************************
285 * acmFilterTagDetailsW (MSACM32.@)
287 MMRESULT WINAPI acmFilterTagDetailsW(HACMDRIVER had, PACMFILTERTAGDETAILSW paftd,
288 DWORD fdwDetails)
290 PWINE_ACMDRIVERID padid;
291 MMRESULT mmr;
293 TRACE("(%p, %p, %ld)\n", had, paftd, fdwDetails);
295 if (fdwDetails & ~(ACM_FILTERTAGDETAILSF_FILTERTAG|ACM_FILTERTAGDETAILSF_INDEX|
296 ACM_FILTERTAGDETAILSF_LARGESTSIZE))
297 return MMSYSERR_INVALFLAG;
299 switch (fdwDetails) {
300 case ACM_FILTERTAGDETAILSF_FILTERTAG:
301 if (had == NULL) {
302 mmr = ACMERR_NOTPOSSIBLE;
303 for (padid = MSACM_pFirstACMDriverID; padid; padid = padid->pNextACMDriverID) {
304 /* should check for codec only */
305 if (!(padid->fdwSupport & ACMDRIVERDETAILS_SUPPORTF_DISABLED) &&
306 acmDriverOpen(&had, (HACMDRIVERID)padid, 0) == 0) {
307 mmr = MSACM_Message(had, ACMDM_FILTERTAG_DETAILS, (LPARAM)paftd, fdwDetails);
308 acmDriverClose(had, 0);
309 if (mmr == MMSYSERR_NOERROR) break;
312 } else {
313 mmr = MSACM_Message(had, ACMDM_FILTERTAG_DETAILS, (LPARAM)paftd, fdwDetails);
315 break;
317 case ACM_FILTERTAGDETAILSF_INDEX:
318 /* FIXME should check paftd->dwFilterTagIndex < add.cFilterTags */
319 mmr = MSACM_Message(had, ACMDM_FILTERTAG_DETAILS, (LPARAM)paftd, fdwDetails);
320 break;
322 case ACM_FILTERTAGDETAILSF_LARGESTSIZE:
323 if (had == NULL) {
324 ACMFILTERTAGDETAILSW tmp;
325 DWORD ft = paftd->dwFilterTag;
327 mmr = ACMERR_NOTPOSSIBLE;
328 for (padid = MSACM_pFirstACMDriverID; padid; padid = padid->pNextACMDriverID) {
329 /* should check for codec only */
330 if (!(padid->fdwSupport & ACMDRIVERDETAILS_SUPPORTF_DISABLED) &&
331 acmDriverOpen(&had, (HACMDRIVERID)padid, 0) == 0) {
333 memset(&tmp, 0, sizeof(tmp));
334 tmp.cbStruct = sizeof(tmp);
335 tmp.dwFilterTag = ft;
337 if (MSACM_Message(had, ACMDM_FILTERTAG_DETAILS,
338 (LPARAM)&tmp, fdwDetails) == MMSYSERR_NOERROR) {
339 if (mmr == ACMERR_NOTPOSSIBLE ||
340 paftd->cbFilterSize < tmp.cbFilterSize) {
341 *paftd = tmp;
342 mmr = MMSYSERR_NOERROR;
345 acmDriverClose(had, 0);
348 } else {
349 mmr = MSACM_Message(had, ACMDM_FILTERTAG_DETAILS, (LPARAM)paftd, fdwDetails);
351 break;
353 default:
354 WARN("Unsupported fdwDetails=%08lx\n", fdwDetails);
355 mmr = MMSYSERR_ERROR;
358 if (mmr == MMSYSERR_NOERROR &&
359 paftd->dwFilterTag == WAVE_FORMAT_PCM && paftd->szFilterTag[0] == 0)
360 MultiByteToWideChar( CP_ACP, 0, "PCM", -1, paftd->szFilterTag,
361 sizeof(paftd->szFilterTag)/sizeof(WCHAR) );
363 return mmr;
366 struct MSACM_FilterTagEnumWtoA_Instance {
367 PACMFILTERTAGDETAILSA paftda;
368 DWORD dwInstance;
369 ACMFILTERTAGENUMCBA fnCallback;
372 static BOOL CALLBACK MSACM_FilterTagEnumCallbackWtoA(HACMDRIVERID hadid,
373 PACMFILTERTAGDETAILSW paftdw,
374 DWORD dwInstance,
375 DWORD fdwSupport)
377 struct MSACM_FilterTagEnumWtoA_Instance* paftei;
379 paftei = (struct MSACM_FilterTagEnumWtoA_Instance*)dwInstance;
381 paftei->paftda->dwFilterTagIndex = paftdw->dwFilterTagIndex;
382 paftei->paftda->dwFilterTag = paftdw->dwFilterTag;
383 paftei->paftda->cbFilterSize = paftdw->cbFilterSize;
384 paftei->paftda->fdwSupport = paftdw->fdwSupport;
385 paftei->paftda->cStandardFilters = paftdw->cStandardFilters;
386 WideCharToMultiByte( CP_ACP, 0, paftdw->szFilterTag, -1, paftei->paftda->szFilterTag,
387 sizeof(paftei->paftda->szFilterTag), NULL, NULL );
389 return (paftei->fnCallback)(hadid, paftei->paftda,
390 paftei->dwInstance, fdwSupport);
393 /***********************************************************************
394 * acmFilterTagEnumA (MSACM32.@)
396 MMRESULT WINAPI acmFilterTagEnumA(HACMDRIVER had, PACMFILTERTAGDETAILSA paftda,
397 ACMFILTERTAGENUMCBA fnCallback, DWORD dwInstance,
398 DWORD fdwEnum)
400 ACMFILTERTAGDETAILSW aftdw;
401 struct MSACM_FilterTagEnumWtoA_Instance aftei;
403 memset(&aftdw, 0, sizeof(aftdw));
404 aftdw.cbStruct = sizeof(aftdw);
405 aftdw.dwFilterTagIndex = paftda->dwFilterTagIndex;
406 aftdw.dwFilterTag = paftda->dwFilterTag;
408 aftei.paftda = paftda;
409 aftei.dwInstance = dwInstance;
410 aftei.fnCallback = fnCallback;
412 return acmFilterTagEnumW(had, &aftdw, MSACM_FilterTagEnumCallbackWtoA,
413 (DWORD)&aftei, fdwEnum);
416 /***********************************************************************
417 * acmFilterTagEnumW (MSACM32.@)
419 MMRESULT WINAPI acmFilterTagEnumW(HACMDRIVER had, PACMFILTERTAGDETAILSW paftd,
420 ACMFILTERTAGENUMCBW fnCallback, DWORD dwInstance,
421 DWORD fdwEnum)
423 PWINE_ACMDRIVERID padid;
424 int i;
426 TRACE("(%p, %p, %p, %ld, %ld)\n",
427 had, paftd, fnCallback, dwInstance, fdwEnum);
429 if (paftd->cbStruct < sizeof(*paftd)) return MMSYSERR_INVALPARAM;
431 if (had) FIXME("had != NULL, not supported\n");
433 for (padid = MSACM_pFirstACMDriverID; padid; padid = padid->pNextACMDriverID) {
434 /* should check for codec only */
435 if (!(padid->fdwSupport & ACMDRIVERDETAILS_SUPPORTF_DISABLED) &&
436 acmDriverOpen(&had, (HACMDRIVERID)padid, 0) == MMSYSERR_NOERROR) {
438 for (i = 0; i < padid->cFilterTags; i++) {
439 paftd->dwFilterTagIndex = i;
440 if (acmFilterTagDetailsW(had, paftd, ACM_FILTERTAGDETAILSF_INDEX) == MMSYSERR_NOERROR) {
441 if (!(fnCallback)((HACMDRIVERID)padid, paftd, dwInstance, padid->fdwSupport)) {
442 padid = NULL;
443 break;
448 acmDriverClose(had, 0);
450 return MMSYSERR_NOERROR;