List 16-bit resources separately as RC_SRCS16.
[wine] / dlls / msacm / filter.c
1 /* -*- tab-width: 8; c-basic-offset: 4 -*- */
2
3 /*
4  *      MSACM32 library
5  *
6  *      Copyright 1998  Patrik Stridvall
7  */
8
9 #include <string.h>
10 #include "winbase.h"
11 #include "winnls.h"
12 #include "winerror.h"
13 #include "mmsystem.h"
14 #include "msacm.h"
15 #include "msacmdrv.h"
16 #include "wineacm.h"
17 #include "debugtools.h"
18
19 DEFAULT_DEBUG_CHANNEL(msacm);
20
21 /***********************************************************************
22  *           acmFilterChooseA (MSACM32.13)
23  */
24 MMRESULT WINAPI acmFilterChooseA(PACMFILTERCHOOSEA pafltrc)
25 {
26     FIXME("(%p): stub\n", pafltrc);
27     SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
28     return MMSYSERR_ERROR;
29 }
30
31 /***********************************************************************
32  *           acmFilterChooseW (MSACM32.14)
33  */
34 MMRESULT WINAPI acmFilterChooseW(PACMFILTERCHOOSEW pafltrc)
35 {
36     FIXME("(%p): stub\n", pafltrc);
37     SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
38     return MMSYSERR_ERROR;
39 }
40
41 /***********************************************************************
42  *           acmFilterDetailsA (MSACM32.15)
43  */
44 MMRESULT WINAPI acmFilterDetailsA(HACMDRIVER had, PACMFILTERDETAILSA pafd, 
45                                   DWORD fdwDetails)
46 {
47     ACMFILTERDETAILSW   afdw;
48     MMRESULT            mmr;
49
50     memset(&afdw, 0, sizeof(afdw));
51     afdw.cbStruct = sizeof(afdw);
52     afdw.dwFilterIndex = pafd->dwFilterIndex;
53     afdw.dwFilterTag = pafd->dwFilterTag; 
54     afdw.pwfltr = pafd->pwfltr;
55     afdw.cbwfltr = pafd->cbwfltr;
56
57     mmr = acmFilterDetailsW(had, &afdw, fdwDetails);
58     if (mmr == MMSYSERR_NOERROR) {
59         pafd->dwFilterTag = afdw.dwFilterTag; 
60         pafd->fdwSupport = afdw.fdwSupport; 
61         WideCharToMultiByte( CP_ACP, 0, afdw.szFilter, -1, pafd->szFilter,
62                              sizeof(pafd->szFilter), NULL, NULL );
63     }
64     return mmr;
65 }
66
67 /***********************************************************************
68  *           acmFilterDetailsW (MSACM32.16)
69  */
70 MMRESULT WINAPI acmFilterDetailsW(HACMDRIVER had, PACMFILTERDETAILSW pafd, 
71                                   DWORD fdwDetails)
72 {
73     MMRESULT                    mmr;
74     ACMFILTERTAGDETAILSA        aftd;
75
76     TRACE("(0x%08x, %p, %ld)\n", had, pafd, fdwDetails);
77
78     memset(&aftd, 0, sizeof(aftd));
79     aftd.cbStruct = sizeof(aftd);
80
81     if (pafd->cbStruct < sizeof(*pafd)) return MMSYSERR_INVALPARAM;
82         
83     switch (fdwDetails) {
84     case ACM_FILTERDETAILSF_FILTER:
85         if (pafd->dwFilterTag != pafd->pwfltr->dwFilterTag) {
86             mmr = MMSYSERR_INVALPARAM;
87             break;
88         }
89         if (had == (HACMDRIVER)NULL) {
90             PWINE_ACMDRIVERID           padid;
91
92             mmr = ACMERR_NOTPOSSIBLE;
93             for (padid = MSACM_pFirstACMDriverID; padid; padid = padid->pNextACMDriverID) {
94                 /* should check for codec only */
95                 if (!(padid->fdwSupport & ACMDRIVERDETAILS_SUPPORTF_DISABLED) &&
96                     acmDriverOpen(&had, (HACMDRIVERID)padid, 0) == 0) {
97                     mmr = MSACM_Message(had, ACMDM_FILTER_DETAILS,
98                                         (LPARAM)pafd, (LPARAM)fdwDetails);
99                     acmDriverClose(had, 0);
100                     if (mmr == MMSYSERR_NOERROR) break;
101                 }
102             }               
103         } else {
104             mmr = MSACM_Message(had, ACMDM_FILTER_DETAILS, (LPARAM)pafd, fdwDetails);
105         }
106         break;
107     case ACM_FILTERDETAILSF_INDEX:
108         /* should check pafd->dwFilterIndex < aftd->cStandardFilters */
109         mmr = MSACM_Message(had, ACMDM_FILTER_DETAILS, (LPARAM)pafd, fdwDetails);
110         break;
111     default:
112         WARN("Unknown fdwDetails %08lx\n", fdwDetails);
113         mmr = MMSYSERR_INVALFLAG;
114         break;
115     }
116
117     TRACE("=> %d\n", mmr);
118     return mmr;
119 }
120
121 struct MSACM_FilterEnumWtoA_Instance {
122     PACMFILTERDETAILSA  pafda;
123     DWORD               dwInstance;
124     ACMFILTERENUMCBA    fnCallback;
125 };
126
127 static BOOL CALLBACK MSACM_FilterEnumCallbackWtoA(HACMDRIVERID hadid,
128                                                   PACMFILTERDETAILSW pafdw,  
129                                                   DWORD dwInstance,             
130                                                   DWORD fdwSupport)
131 {
132     struct MSACM_FilterEnumWtoA_Instance* pafei;
133
134     pafei = (struct MSACM_FilterEnumWtoA_Instance*)dwInstance;
135
136     pafei->pafda->dwFilterIndex = pafdw->dwFilterIndex; 
137     pafei->pafda->dwFilterTag = pafdw->dwFilterTag; 
138     pafei->pafda->fdwSupport = pafdw->fdwSupport; 
139     WideCharToMultiByte( CP_ACP, 0, pafdw->szFilter, -1, pafei->pafda->szFilter,
140                          sizeof(pafei->pafda->szFilter), NULL, NULL );
141
142     return (pafei->fnCallback)(hadid, pafei->pafda, 
143                                pafei->dwInstance, fdwSupport);
144 }
145
146 /***********************************************************************
147  *           acmFilterEnumA (MSACM32.17)
148  */
149 MMRESULT WINAPI acmFilterEnumA(HACMDRIVER had, PACMFILTERDETAILSA pafda, 
150                                ACMFILTERENUMCBA fnCallback, DWORD dwInstance, 
151                                DWORD fdwEnum)
152 {
153     ACMFILTERDETAILSW           afdw;
154     struct MSACM_FilterEnumWtoA_Instance afei;
155
156     memset(&afdw, 0, sizeof(afdw));
157     afdw.cbStruct = sizeof(afdw);
158     afdw.dwFilterIndex = pafda->dwFilterIndex;
159     afdw.dwFilterTag = pafda->dwFilterTag;
160     afdw.pwfltr = pafda->pwfltr;
161     afdw.cbwfltr = pafda->cbwfltr;
162
163     afei.pafda = pafda;
164     afei.dwInstance = dwInstance;
165     afei.fnCallback = fnCallback;
166
167     return acmFilterEnumW(had, &afdw, MSACM_FilterEnumCallbackWtoA, 
168                           (DWORD)&afei, fdwEnum);
169 }
170
171 static BOOL MSACM_FilterEnumHelper(PWINE_ACMDRIVERID padid, HACMDRIVER had, 
172                                    PACMFILTERDETAILSW pafd, 
173                                    ACMFILTERENUMCBW fnCallback, DWORD dwInstance,  
174                                    DWORD fdwEnum)
175 {
176     ACMFILTERTAGDETAILSW        aftd;
177     int                         i, j;
178
179     for (i = 0; i < padid->cFilterTags; i++) {
180         memset(&aftd, 0, sizeof(aftd));
181         aftd.cbStruct = sizeof(aftd);
182         aftd.dwFilterTagIndex = i;
183         if (acmFilterTagDetailsW(had, &aftd, ACM_FILTERTAGDETAILSF_INDEX) != MMSYSERR_NOERROR)
184             continue;
185         
186         if ((fdwEnum & ACM_FILTERENUMF_DWFILTERTAG) && 
187             aftd.dwFilterTag != pafd->pwfltr->dwFilterTag)
188             continue;
189         
190         for (j = 0; j < aftd.cStandardFilters; j++) {
191             pafd->dwFilterIndex = j;
192             pafd->dwFilterTag = aftd.dwFilterTag;
193             if (acmFilterDetailsW(had, pafd, ACM_FILTERDETAILSF_INDEX) != MMSYSERR_NOERROR) 
194                 continue;
195             
196             if (!(fnCallback)((HACMDRIVERID)padid, pafd, dwInstance, padid->fdwSupport))
197                 return FALSE; 
198         }
199     }
200     return TRUE;
201 }
202
203 /***********************************************************************
204  *           acmFilterEnumW (MSACM32.18)
205  */
206 MMRESULT WINAPI acmFilterEnumW(HACMDRIVER had, PACMFILTERDETAILSW pafd, 
207                                ACMFILTERENUMCBW fnCallback, DWORD dwInstance, 
208                                DWORD fdwEnum)
209 {
210     PWINE_ACMDRIVERID           padid;
211     BOOL                        ret;
212
213     TRACE("(0x%08x, %p, %p, %ld, %ld)\n",
214           had, pafd, fnCallback, dwInstance, fdwEnum);
215
216     if (pafd->cbStruct < sizeof(*pafd)) return MMSYSERR_INVALPARAM;
217
218     if (fdwEnum & ~(ACM_FILTERENUMF_DWFILTERTAG))
219         FIXME("Unsupported fdwEnum values\n");
220
221     if (had) {
222         HACMDRIVERID    hadid;
223
224         if (acmDriverID(had, &hadid, 0) != MMSYSERR_NOERROR)
225             return MMSYSERR_INVALHANDLE;
226         MSACM_FilterEnumHelper(MSACM_GetDriverID(hadid), had, pafd,
227                                fnCallback, dwInstance, fdwEnum);
228         return MMSYSERR_NOERROR;
229     }
230     for (padid = MSACM_pFirstACMDriverID; padid; padid = padid->pNextACMDriverID) {
231             /* should check for codec only */
232             if ((padid->fdwSupport & ACMDRIVERDETAILS_SUPPORTF_DISABLED) || 
233                 acmDriverOpen(&had, (HACMDRIVERID)padid, 0) != MMSYSERR_NOERROR)
234                 continue;
235             ret = MSACM_FilterEnumHelper(padid, had, pafd, 
236                                          fnCallback, dwInstance, fdwEnum);
237             acmDriverClose(had, 0);
238             if (!ret) break;
239     }
240     return MMSYSERR_NOERROR;
241 }
242
243 /***********************************************************************
244  *           acmFilterTagDetailsA (MSACM32.19)
245  */
246 MMRESULT WINAPI acmFilterTagDetailsA(HACMDRIVER had, PACMFILTERTAGDETAILSA paftda, 
247                                      DWORD fdwDetails)
248 {
249     ACMFILTERTAGDETAILSW        aftdw;
250     MMRESULT                    mmr;
251
252     memset(&aftdw, 0, sizeof(aftdw));
253     aftdw.cbStruct = sizeof(aftdw);
254     aftdw.dwFilterTagIndex = paftda->dwFilterTagIndex;
255     aftdw.dwFilterTag = paftda->dwFilterTag;
256
257     mmr = acmFilterTagDetailsW(had, &aftdw, fdwDetails);
258     if (mmr == MMSYSERR_NOERROR) {
259         paftda->dwFilterTag = aftdw.dwFilterTag; 
260         paftda->dwFilterTagIndex = aftdw.dwFilterTagIndex;
261         paftda->cbFilterSize = aftdw.cbFilterSize; 
262         paftda->fdwSupport = aftdw.fdwSupport; 
263         paftda->cStandardFilters = aftdw.cStandardFilters; 
264         WideCharToMultiByte( CP_ACP, 0, aftdw.szFilterTag, -1, paftda->szFilterTag,
265                              sizeof(paftda->szFilterTag), NULL, NULL );
266     }
267     return mmr;
268 }
269
270 /***********************************************************************
271  *           acmFilterTagDetailsW (MSACM32.20)
272  */
273 MMRESULT WINAPI acmFilterTagDetailsW(HACMDRIVER had, PACMFILTERTAGDETAILSW paftd, 
274                                      DWORD fdwDetails)
275 {
276     PWINE_ACMDRIVERID   padid;
277     MMRESULT            mmr;
278
279     TRACE("(0x%08x, %p, %ld)\n", had, paftd, fdwDetails);
280
281     if (fdwDetails & ~(ACM_FILTERTAGDETAILSF_FILTERTAG|ACM_FILTERTAGDETAILSF_INDEX|
282                        ACM_FILTERTAGDETAILSF_LARGESTSIZE))
283         return MMSYSERR_INVALFLAG;
284
285     switch (fdwDetails) {
286     case ACM_FILTERTAGDETAILSF_FILTERTAG:
287         if (had == (HACMDRIVER)NULL) {
288             mmr = ACMERR_NOTPOSSIBLE;
289             for (padid = MSACM_pFirstACMDriverID; padid; padid = padid->pNextACMDriverID) {
290                 /* should check for codec only */
291                 if (!(padid->fdwSupport & ACMDRIVERDETAILS_SUPPORTF_DISABLED) &&
292                       acmDriverOpen(&had, (HACMDRIVERID)padid, 0) == 0) {
293                     mmr = MSACM_Message(had, ACMDM_FILTERTAG_DETAILS, (LPARAM)paftd, fdwDetails);
294                     acmDriverClose(had, 0);
295                     if (mmr == MMSYSERR_NOERROR) break;
296                 }
297             }
298         } else {
299             mmr = MSACM_Message(had, ACMDM_FILTERTAG_DETAILS, (LPARAM)paftd, fdwDetails);
300         }
301         break;
302
303     case ACM_FILTERTAGDETAILSF_INDEX:
304         /* FIXME should check paftd->dwFilterTagIndex < add.cFilterTags */
305         mmr = MSACM_Message(had, ACMDM_FILTERTAG_DETAILS, (LPARAM)paftd, fdwDetails);
306         break;
307
308     case ACM_FILTERTAGDETAILSF_LARGESTSIZE:
309         if (had == (HACMDRIVER)NULL) {
310             ACMFILTERTAGDETAILSW        tmp;
311             DWORD                       ft = paftd->dwFilterTag;
312
313             mmr = ACMERR_NOTPOSSIBLE;
314             for (padid = MSACM_pFirstACMDriverID; padid; padid = padid->pNextACMDriverID) {
315                 /* should check for codec only */
316                 if (!(padid->fdwSupport & ACMDRIVERDETAILS_SUPPORTF_DISABLED) && 
317                     acmDriverOpen(&had, (HACMDRIVERID)padid, 0) == 0) {
318
319                     memset(&tmp, 0, sizeof(tmp));
320                     tmp.cbStruct = sizeof(tmp);
321                     tmp.dwFilterTag = ft;
322
323                     if (MSACM_Message(had, ACMDM_FILTERTAG_DETAILS, 
324                                       (LPARAM)&tmp, fdwDetails) == MMSYSERR_NOERROR) {
325                         if (mmr == ACMERR_NOTPOSSIBLE ||
326                             paftd->cbFilterSize < tmp.cbFilterSize) {
327                             *paftd = tmp;
328                             mmr = MMSYSERR_NOERROR;
329                         } 
330                     }
331                     acmDriverClose(had, 0);
332                 }
333             }
334         } else {
335             mmr = MSACM_Message(had, ACMDM_FILTERTAG_DETAILS, (LPARAM)paftd, fdwDetails);
336         }
337         break;
338
339     default:
340         WARN("Unsupported fdwDetails=%08lx\n", fdwDetails);
341         mmr = MMSYSERR_ERROR;
342     }
343
344     if (mmr == MMSYSERR_NOERROR && 
345         paftd->dwFilterTag == WAVE_FORMAT_PCM && paftd->szFilterTag[0] == 0)
346         MultiByteToWideChar( CP_ACP, 0, "PCM", -1, paftd->szFilterTag,
347                              sizeof(paftd->szFilterTag)/sizeof(WCHAR) );
348
349     return mmr;
350 }
351
352 struct MSACM_FilterTagEnumWtoA_Instance {
353     PACMFILTERTAGDETAILSA       paftda;
354     DWORD                       dwInstance;
355     ACMFILTERTAGENUMCBA         fnCallback;
356 };
357
358 static BOOL CALLBACK MSACM_FilterTagEnumCallbackWtoA(HACMDRIVERID hadid,
359                                                      PACMFILTERTAGDETAILSW paftdw,  
360                                                      DWORD dwInstance,             
361                                                      DWORD fdwSupport)
362 {
363     struct MSACM_FilterTagEnumWtoA_Instance* paftei;
364
365     paftei = (struct MSACM_FilterTagEnumWtoA_Instance*)dwInstance;
366
367     paftei->paftda->dwFilterTagIndex = paftdw->dwFilterTagIndex; 
368     paftei->paftda->dwFilterTag = paftdw->dwFilterTag; 
369     paftei->paftda->cbFilterSize = paftdw->cbFilterSize; 
370     paftei->paftda->fdwSupport = paftdw->fdwSupport; 
371     paftei->paftda->cStandardFilters = paftdw->cStandardFilters; 
372     WideCharToMultiByte( CP_ACP, 0, paftdw->szFilterTag, -1, paftei->paftda->szFilterTag,
373                          sizeof(paftei->paftda->szFilterTag), NULL, NULL );
374
375     return (paftei->fnCallback)(hadid, paftei->paftda, 
376                                 paftei->dwInstance, fdwSupport);
377 }
378
379 /***********************************************************************
380  *           acmFilterTagEnumA (MSACM32.21)
381  */
382 MMRESULT WINAPI acmFilterTagEnumA(HACMDRIVER had, PACMFILTERTAGDETAILSA paftda,
383                                   ACMFILTERTAGENUMCBA fnCallback, DWORD dwInstance, 
384                                   DWORD fdwEnum)
385 {
386     ACMFILTERTAGDETAILSW        aftdw;
387     struct MSACM_FilterTagEnumWtoA_Instance aftei;
388
389     memset(&aftdw, 0, sizeof(aftdw));
390     aftdw.cbStruct = sizeof(aftdw);
391     aftdw.dwFilterTagIndex = paftda->dwFilterTagIndex;
392     aftdw.dwFilterTag = paftda->dwFilterTag;
393
394     aftei.paftda = paftda;
395     aftei.dwInstance = dwInstance;
396     aftei.fnCallback = fnCallback;
397
398     return acmFilterTagEnumW(had, &aftdw, MSACM_FilterTagEnumCallbackWtoA, 
399                              (DWORD)&aftei, fdwEnum);
400 }
401
402 /***********************************************************************
403  *           acmFilterTagEnumW (MSACM32.22)
404  */
405 MMRESULT WINAPI acmFilterTagEnumW(HACMDRIVER had, PACMFILTERTAGDETAILSW paftd,
406                                   ACMFILTERTAGENUMCBW fnCallback, DWORD dwInstance, 
407                                   DWORD fdwEnum)
408 {
409     PWINE_ACMDRIVERID           padid;
410     int                         i;
411
412     TRACE("(0x%08x, %p, %p, %ld, %ld)\n",
413           had, paftd, fnCallback, dwInstance, fdwEnum); 
414
415     if (paftd->cbStruct < sizeof(*paftd)) return MMSYSERR_INVALPARAM;
416
417     if (had) FIXME("had != NULL, not supported\n");
418     
419     for (padid = MSACM_pFirstACMDriverID; padid; padid = padid->pNextACMDriverID) {
420         /* should check for codec only */
421         if (!(padid->fdwSupport & ACMDRIVERDETAILS_SUPPORTF_DISABLED) &&
422             acmDriverOpen(&had, (HACMDRIVERID)padid, 0) == MMSYSERR_NOERROR) {
423
424             for (i = 0; i < padid->cFilterTags; i++) {
425                 paftd->dwFilterTagIndex = i;
426                 if (acmFilterTagDetailsW(had, paftd, ACM_FILTERTAGDETAILSF_INDEX) == MMSYSERR_NOERROR) {
427                     if (!(fnCallback)((HACMDRIVERID)padid, paftd, dwInstance, padid->fdwSupport)) {
428                         padid = NULL;
429                         break;
430                     }
431                 }
432             }
433         }
434         acmDriverClose(had, 0);
435     }
436     return MMSYSERR_NOERROR;
437 }