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