1 | /* -*- tab-width: 8; c-basic-offset: 4 -*- */
|
---|
2 | /* $Id: format.c,v 1.2 2001-09-05 13:11:25 bird Exp $ */
|
---|
3 | /*
|
---|
4 | * MSACM32 library
|
---|
5 | *
|
---|
6 | * Copyright 1998 Patrik Stridvall
|
---|
7 | * 2000 Eric Pouech
|
---|
8 | */
|
---|
9 |
|
---|
10 | #include <string.h>
|
---|
11 | #include "winbase.h"
|
---|
12 | #include "winnls.h"
|
---|
13 | #include "winerror.h"
|
---|
14 | #include "windef.h"
|
---|
15 | #include "wingdi.h"
|
---|
16 | #include "winuser.h"
|
---|
17 | #include "wine/unicode.h"
|
---|
18 | #include "debugtools.h"
|
---|
19 | #include "mmsystem.h"
|
---|
20 | #include "msacm.h"
|
---|
21 | #include "msacmdrv.h"
|
---|
22 | #include "wineacm.h"
|
---|
23 |
|
---|
24 | DEFAULT_DEBUG_CHANNEL(msacm);
|
---|
25 |
|
---|
26 | static PACMFORMATCHOOSEA afc;
|
---|
27 |
|
---|
28 | struct MSACM_FillFormatData {
|
---|
29 | HWND hWnd;
|
---|
30 | #define WINE_ACMFF_TAG 0
|
---|
31 | #define WINE_ACMFF_FORMAT 1
|
---|
32 | #define WINE_ACMFF_WFX 2
|
---|
33 | int mode;
|
---|
34 | char szFormatTag[ACMFORMATTAGDETAILS_FORMATTAG_CHARS];
|
---|
35 | PACMFORMATCHOOSEA afc;
|
---|
36 | DWORD ret;
|
---|
37 | };
|
---|
38 |
|
---|
39 | static BOOL CALLBACK MSACM_FillFormatTagsCB(HACMDRIVERID hadid,
|
---|
40 | PACMFORMATTAGDETAILSA paftd,
|
---|
41 | DWORD dwInstance, DWORD fdwSupport)
|
---|
42 | {
|
---|
43 | struct MSACM_FillFormatData* affd = (struct MSACM_FillFormatData*)dwInstance;
|
---|
44 |
|
---|
45 | switch (affd->mode) {
|
---|
46 | case WINE_ACMFF_TAG:
|
---|
47 | if (SendDlgItemMessageA(affd->hWnd, IDD_ACMFORMATCHOOSE_CMB_FORMATTAG,
|
---|
48 | CB_FINDSTRINGEXACT,
|
---|
49 | (WPARAM)-1, (LPARAM)paftd->szFormatTag) == CB_ERR)
|
---|
50 | SendDlgItemMessageA(affd->hWnd, IDD_ACMFORMATCHOOSE_CMB_FORMATTAG,
|
---|
51 | CB_ADDSTRING, 0, (DWORD)paftd->szFormatTag);
|
---|
52 | break;
|
---|
53 | case WINE_ACMFF_FORMAT:
|
---|
54 | if (strcmp(affd->szFormatTag, paftd->szFormatTag) == 0) {
|
---|
55 | HACMDRIVER had;
|
---|
56 |
|
---|
57 | if (acmDriverOpen(&had, hadid, 0) == MMSYSERR_NOERROR) {
|
---|
58 | ACMFORMATDETAILSA afd;
|
---|
59 | int i, idx;
|
---|
60 | MMRESULT mmr;
|
---|
61 | char buffer[64];
|
---|
62 |
|
---|
63 | afd.cbStruct = sizeof(afd);
|
---|
64 | afd.dwFormatTag = paftd->dwFormatTag;
|
---|
65 | afd.pwfx = HeapAlloc(GetProcessHeap(), 0, paftd->cbFormatSize);
|
---|
66 | afd.pwfx->wFormatTag = paftd->dwFormatTag;
|
---|
67 | afd.pwfx->cbSize = paftd->cbFormatSize;
|
---|
68 | afd.cbwfx = paftd->cbFormatSize;
|
---|
69 |
|
---|
70 | for (i = 0; i < paftd->cStandardFormats; i++) {
|
---|
71 | afd.dwFormatIndex = i;
|
---|
72 | mmr = acmFormatDetailsA(had, &afd, ACM_FORMATDETAILSF_INDEX);
|
---|
73 | if (mmr == MMSYSERR_NOERROR) {
|
---|
74 | strcpy(buffer, afd.szFormat);
|
---|
75 | for (idx = strlen(buffer);
|
---|
76 | idx < ACMFORMATTAGDETAILS_FORMATTAG_CHARS; idx++)
|
---|
77 | buffer[idx] = ' ';
|
---|
78 | wsprintfA(buffer + ACMFORMATTAGDETAILS_FORMATTAG_CHARS,
|
---|
79 | "%d Ko/s",
|
---|
80 | (afd.pwfx->nAvgBytesPerSec + 512) / 1024);
|
---|
81 | SendDlgItemMessageA(affd->hWnd,
|
---|
82 | IDD_ACMFORMATCHOOSE_CMB_FORMAT,
|
---|
83 | CB_ADDSTRING, 0, (DWORD)buffer);
|
---|
84 | }
|
---|
85 | }
|
---|
86 | acmDriverClose(had, 0);
|
---|
87 | SendDlgItemMessageA(affd->hWnd, IDD_ACMFORMATCHOOSE_CMB_FORMAT,
|
---|
88 | CB_SETCURSEL, 0, 0);
|
---|
89 | }
|
---|
90 | }
|
---|
91 | break;
|
---|
92 | case WINE_ACMFF_WFX:
|
---|
93 | if (strcmp(affd->szFormatTag, paftd->szFormatTag) == 0) {
|
---|
94 | HACMDRIVER had;
|
---|
95 |
|
---|
96 | if (acmDriverOpen(&had, hadid, 0) == MMSYSERR_NOERROR) {
|
---|
97 | ACMFORMATDETAILSA afd;
|
---|
98 |
|
---|
99 | afd.cbStruct = sizeof(afd);
|
---|
100 | afd.dwFormatTag = paftd->dwFormatTag;
|
---|
101 | afd.pwfx = affd->afc->pwfx;
|
---|
102 | afd.cbwfx = affd->afc->cbwfx;
|
---|
103 |
|
---|
104 | afd.dwFormatIndex = SendDlgItemMessageA(affd->hWnd, IDD_ACMFORMATCHOOSE_CMB_FORMAT, CB_GETCURSEL, 0, 0);;
|
---|
105 | affd->ret = acmFormatDetailsA(had, &afd, ACM_FORMATDETAILSF_INDEX);
|
---|
106 | acmDriverClose(had, 0);
|
---|
107 | return TRUE;
|
---|
108 | }
|
---|
109 | }
|
---|
110 | break;
|
---|
111 | default:
|
---|
112 | FIXME("Unknown mode (%d)\n", affd->mode);
|
---|
113 | break;
|
---|
114 | }
|
---|
115 | return TRUE;
|
---|
116 | }
|
---|
117 |
|
---|
118 | static BOOL MSACM_FillFormatTags(HWND hWnd)
|
---|
119 | {
|
---|
120 | ACMFORMATTAGDETAILSA aftd;
|
---|
121 | struct MSACM_FillFormatData affd;
|
---|
122 |
|
---|
123 | memset(&aftd, 0, sizeof(aftd));
|
---|
124 | aftd.cbStruct = sizeof(aftd);
|
---|
125 |
|
---|
126 | affd.hWnd = hWnd;
|
---|
127 | affd.mode = WINE_ACMFF_TAG;
|
---|
128 |
|
---|
129 | acmFormatTagEnumA((HACMDRIVER)0, &aftd, MSACM_FillFormatTagsCB, (DWORD)&affd, 0);
|
---|
130 | SendDlgItemMessageA(hWnd, IDD_ACMFORMATCHOOSE_CMB_FORMATTAG, CB_SETCURSEL, 0, 0);
|
---|
131 | return TRUE;
|
---|
132 | }
|
---|
133 |
|
---|
134 | static BOOL MSACM_FillFormat(HWND hWnd)
|
---|
135 | {
|
---|
136 | ACMFORMATTAGDETAILSA aftd;
|
---|
137 | struct MSACM_FillFormatData affd;
|
---|
138 |
|
---|
139 | SendDlgItemMessageA(hWnd, IDD_ACMFORMATCHOOSE_CMB_FORMAT, CB_RESETCONTENT, 0, 0);
|
---|
140 |
|
---|
141 | memset(&aftd, 0, sizeof(aftd));
|
---|
142 | aftd.cbStruct = sizeof(aftd);
|
---|
143 |
|
---|
144 | affd.hWnd = hWnd;
|
---|
145 | affd.mode = WINE_ACMFF_FORMAT;
|
---|
146 | SendDlgItemMessageA(hWnd, IDD_ACMFORMATCHOOSE_CMB_FORMATTAG,
|
---|
147 | CB_GETLBTEXT,
|
---|
148 | SendDlgItemMessageA(hWnd, IDD_ACMFORMATCHOOSE_CMB_FORMATTAG,
|
---|
149 | CB_GETCURSEL, 0, 0),
|
---|
150 | (DWORD)affd.szFormatTag);
|
---|
151 |
|
---|
152 | acmFormatTagEnumA((HACMDRIVER)0, &aftd, MSACM_FillFormatTagsCB, (DWORD)&affd, 0);
|
---|
153 | SendDlgItemMessageA(hWnd, IDD_ACMFORMATCHOOSE_CMB_FORMAT, CB_SETCURSEL, 0, 0);
|
---|
154 | return TRUE;
|
---|
155 | }
|
---|
156 |
|
---|
157 | static MMRESULT MSACM_GetWFX(HWND hWnd, PACMFORMATCHOOSEA afc)
|
---|
158 | {
|
---|
159 | ACMFORMATTAGDETAILSA aftd;
|
---|
160 | struct MSACM_FillFormatData affd;
|
---|
161 |
|
---|
162 | memset(&aftd, 0, sizeof(aftd));
|
---|
163 | aftd.cbStruct = sizeof(aftd);
|
---|
164 |
|
---|
165 | affd.hWnd = hWnd;
|
---|
166 | affd.mode = WINE_ACMFF_WFX;
|
---|
167 | affd.afc = afc;
|
---|
168 | affd.ret = MMSYSERR_NOERROR;
|
---|
169 |
|
---|
170 | acmFormatTagEnumA((HACMDRIVER)0, &aftd, MSACM_FillFormatTagsCB, (DWORD)&affd, 0);
|
---|
171 | return affd.ret;
|
---|
172 | }
|
---|
173 |
|
---|
174 | static BOOL WINAPI FormatChooseDlgProc(HWND hWnd, UINT msg,
|
---|
175 | WPARAM wParam, LPARAM lParam)
|
---|
176 | {
|
---|
177 |
|
---|
178 | TRACE("hwnd=%i msg=%i 0x%08x 0x%08lx\n", hWnd, msg, wParam, lParam );
|
---|
179 |
|
---|
180 | switch (msg) {
|
---|
181 | case WM_INITDIALOG:
|
---|
182 | afc = (PACMFORMATCHOOSEA)lParam;
|
---|
183 | MSACM_FillFormatTags(hWnd);
|
---|
184 | MSACM_FillFormat(hWnd);
|
---|
185 | if ((afc->fdwStyle & ~(ACMFORMATCHOOSE_STYLEF_CONTEXTHELP|
|
---|
186 | ACMFORMATCHOOSE_STYLEF_SHOWHELP)) != 0)
|
---|
187 | FIXME("Unsupported style %08lx\n", ((PACMFORMATCHOOSEA)lParam)->fdwStyle);
|
---|
188 | if (!(afc->fdwStyle & ACMFORMATCHOOSE_STYLEF_SHOWHELP))
|
---|
189 | ShowWindow(GetDlgItem(hWnd, IDD_ACMFORMATCHOOSE_BTN_HELP), SW_HIDE);
|
---|
190 | return TRUE;
|
---|
191 |
|
---|
192 | case WM_COMMAND:
|
---|
193 | switch (LOWORD(wParam)) {
|
---|
194 | case IDOK:
|
---|
195 | EndDialog(hWnd, MSACM_GetWFX(hWnd, afc));
|
---|
196 | return TRUE;
|
---|
197 | case IDCANCEL:
|
---|
198 | EndDialog(hWnd, ACMERR_CANCELED);
|
---|
199 | return TRUE;
|
---|
200 | case IDD_ACMFORMATCHOOSE_CMB_FORMATTAG:
|
---|
201 | switch (HIWORD(wParam)) {
|
---|
202 | case CBN_SELCHANGE:
|
---|
203 | MSACM_FillFormat(hWnd);
|
---|
204 | break;
|
---|
205 | default:
|
---|
206 | TRACE("Dropped dlgNotif (fmtTag): 0x%08x 0x%08lx\n",
|
---|
207 | HIWORD(wParam), lParam);
|
---|
208 | break;
|
---|
209 | }
|
---|
210 | break;
|
---|
211 | case IDD_ACMFORMATCHOOSE_BTN_HELP:
|
---|
212 | if (afc->fdwStyle & ACMFORMATCHOOSE_STYLEF_SHOWHELP)
|
---|
213 | SendMessageA(afc->hwndOwner,
|
---|
214 | RegisterWindowMessageA(ACMHELPMSGSTRINGA), 0L, 0L);
|
---|
215 | break;
|
---|
216 |
|
---|
217 | default:
|
---|
218 | TRACE("Dropped dlgCmd: ctl=%d ntf=0x%04x 0x%08lx\n",
|
---|
219 | LOWORD(wParam), HIWORD(wParam), lParam);
|
---|
220 | break;
|
---|
221 | }
|
---|
222 | break;
|
---|
223 | case WM_CONTEXTMENU:
|
---|
224 | if (afc->fdwStyle & ACMFORMATCHOOSE_STYLEF_CONTEXTHELP)
|
---|
225 | SendMessageA(afc->hwndOwner,
|
---|
226 | RegisterWindowMessageA(ACMHELPMSGCONTEXTMENUA),
|
---|
227 | wParam, lParam);
|
---|
228 | break;
|
---|
229 | #if defined(WM_CONTEXTHELP)
|
---|
230 | case WM_CONTEXTHELP:
|
---|
231 | if (afc->fdwStyle & ACMFORMATCHOOSE_STYLEF_CONTEXTHELP)
|
---|
232 | SendMessageA(afc->hwndOwner,
|
---|
233 | RegisterWindowMessageA(ACMHELPMSGCONTEXTHELPA),
|
---|
234 | wParam, lParam);
|
---|
235 | break;
|
---|
236 | #endif
|
---|
237 | default:
|
---|
238 | TRACE("Dropped dlgMsg: hwnd=%i msg=%i 0x%08x 0x%08lx\n",
|
---|
239 | hWnd, msg, wParam, lParam );
|
---|
240 | break;
|
---|
241 | }
|
---|
242 | return FALSE;
|
---|
243 | }
|
---|
244 |
|
---|
245 | /***********************************************************************
|
---|
246 | * acmFormatChooseA (MSACM32.23)
|
---|
247 | */
|
---|
248 | MMRESULT WINAPI acmFormatChooseA(PACMFORMATCHOOSEA pafmtc)
|
---|
249 | {
|
---|
250 | return DialogBoxParamA(MSACM_hInstance32, MAKEINTRESOURCEA(DLG_ACMFORMATCHOOSE_ID),
|
---|
251 | pafmtc->hwndOwner, FormatChooseDlgProc, (INT)pafmtc);
|
---|
252 | }
|
---|
253 |
|
---|
254 | /***********************************************************************
|
---|
255 | * acmFormatChooseW (MSACM32.24)
|
---|
256 | */
|
---|
257 | MMRESULT WINAPI acmFormatChooseW(PACMFORMATCHOOSEW pafmtc)
|
---|
258 | {
|
---|
259 | FIXME("(%p): stub\n", pafmtc);
|
---|
260 | SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
---|
261 | return MMSYSERR_ERROR;
|
---|
262 | }
|
---|
263 |
|
---|
264 | /***********************************************************************
|
---|
265 | * acmFormatDetailsA (MSACM32.25)
|
---|
266 | */
|
---|
267 | MMRESULT WINAPI acmFormatDetailsA(HACMDRIVER had, PACMFORMATDETAILSA pafd,
|
---|
268 | DWORD fdwDetails)
|
---|
269 | {
|
---|
270 | ACMFORMATDETAILSW afdw;
|
---|
271 | MMRESULT mmr;
|
---|
272 |
|
---|
273 | memset(&afdw, 0, sizeof(afdw));
|
---|
274 | afdw.cbStruct = sizeof(afdw);
|
---|
275 | afdw.dwFormatIndex = pafd->dwFormatIndex;
|
---|
276 | afdw.dwFormatTag = pafd->dwFormatTag;
|
---|
277 | afdw.pwfx = pafd->pwfx;
|
---|
278 | afdw.cbwfx = pafd->cbwfx;
|
---|
279 |
|
---|
280 | mmr = acmFormatDetailsW(had, &afdw, fdwDetails);
|
---|
281 | if (mmr == MMSYSERR_NOERROR) {
|
---|
282 | pafd->dwFormatTag = afdw.dwFormatTag;
|
---|
283 | pafd->fdwSupport = afdw.fdwSupport;
|
---|
284 | WideCharToMultiByte( CP_ACP, 0, afdw.szFormat, -1,
|
---|
285 | pafd->szFormat, sizeof(pafd->szFormat), NULL, NULL );
|
---|
286 | }
|
---|
287 | return mmr;
|
---|
288 | }
|
---|
289 |
|
---|
290 | /***********************************************************************
|
---|
291 | * acmFormatDetailsW (MSACM32.26)
|
---|
292 | */
|
---|
293 | MMRESULT WINAPI acmFormatDetailsW(HACMDRIVER had, PACMFORMATDETAILSW pafd,
|
---|
294 | DWORD fdwDetails)
|
---|
295 | {
|
---|
296 | MMRESULT mmr;
|
---|
297 | static WCHAR fmt1[] = {'%','d',' ','H','z',0};
|
---|
298 | static WCHAR fmt2[] = {';',' ','%','d',' ','b','i','t','s',0};
|
---|
299 | ACMFORMATTAGDETAILSA aftd;
|
---|
300 |
|
---|
301 | TRACE("(0x%08x, %p, %ld)\n", had, pafd, fdwDetails);
|
---|
302 |
|
---|
303 | memset(&aftd, 0, sizeof(aftd));
|
---|
304 | aftd.cbStruct = sizeof(aftd);
|
---|
305 |
|
---|
306 | if (pafd->cbStruct < sizeof(*pafd)) return MMSYSERR_INVALPARAM;
|
---|
307 |
|
---|
308 | switch (fdwDetails) {
|
---|
309 | case ACM_FORMATDETAILSF_FORMAT:
|
---|
310 | if (pafd->dwFormatTag != pafd->pwfx->wFormatTag) {
|
---|
311 | mmr = MMSYSERR_INVALPARAM;
|
---|
312 | break;
|
---|
313 | }
|
---|
314 | if (had == (HACMDRIVER)NULL) {
|
---|
315 | PWINE_ACMDRIVERID padid;
|
---|
316 |
|
---|
317 | mmr = ACMERR_NOTPOSSIBLE;
|
---|
318 | for (padid = MSACM_pFirstACMDriverID; padid; padid = padid->pNextACMDriverID) {
|
---|
319 | /* should check for codec only */
|
---|
320 | if (padid->bEnabled &&
|
---|
321 | acmDriverOpen(&had, (HACMDRIVERID)padid, 0) == 0) {
|
---|
322 | mmr = MSACM_Message(had, ACMDM_FORMAT_DETAILS,
|
---|
323 | (LPARAM)pafd, (LPARAM)fdwDetails);
|
---|
324 | acmDriverClose(had, 0);
|
---|
325 | if (mmr == MMSYSERR_NOERROR) break;
|
---|
326 | }
|
---|
327 | }
|
---|
328 | } else {
|
---|
329 | mmr = MSACM_Message(had, ACMDM_FORMAT_DETAILS,
|
---|
330 | (LPARAM)pafd, (LPARAM)fdwDetails);
|
---|
331 | }
|
---|
332 | break;
|
---|
333 | case ACM_FORMATDETAILSF_INDEX:
|
---|
334 | /* should check pafd->dwFormatIndex < aftd->cStandardFormats */
|
---|
335 | mmr = MSACM_Message(had, ACMDM_FORMAT_DETAILS,
|
---|
336 | (LPARAM)pafd, (LPARAM)fdwDetails);
|
---|
337 | break;
|
---|
338 | default:
|
---|
339 | WARN("Unknown fdwDetails %08lx\n", fdwDetails);
|
---|
340 | mmr = MMSYSERR_INVALFLAG;
|
---|
341 | break;
|
---|
342 | }
|
---|
343 |
|
---|
344 | if (mmr == MMSYSERR_NOERROR && pafd->szFormat[0] == (WCHAR)0) {
|
---|
345 | wsprintfW(pafd->szFormat, fmt1, pafd->pwfx->nSamplesPerSec);
|
---|
346 | if (pafd->pwfx->wBitsPerSample) {
|
---|
347 | wsprintfW(pafd->szFormat + lstrlenW(pafd->szFormat), fmt2,
|
---|
348 | pafd->pwfx->wBitsPerSample);
|
---|
349 | }
|
---|
350 | MultiByteToWideChar( CP_ACP, 0, (pafd->pwfx->nChannels == 1) ? "; Mono" : "; Stereo", -1,
|
---|
351 | pafd->szFormat + strlenW(pafd->szFormat),
|
---|
352 | sizeof(pafd->szFormat)/sizeof(WCHAR) - strlenW(pafd->szFormat) );
|
---|
353 | }
|
---|
354 |
|
---|
355 | TRACE("=> %d\n", mmr);
|
---|
356 | return mmr;
|
---|
357 | }
|
---|
358 |
|
---|
359 | struct MSACM_FormatEnumWtoA_Instance {
|
---|
360 | PACMFORMATDETAILSA pafda;
|
---|
361 | DWORD dwInstance;
|
---|
362 | ACMFORMATENUMCBA fnCallback;
|
---|
363 | };
|
---|
364 |
|
---|
365 | static BOOL CALLBACK MSACM_FormatEnumCallbackWtoA(HACMDRIVERID hadid,
|
---|
366 | PACMFORMATDETAILSW pafdw,
|
---|
367 | DWORD dwInstance,
|
---|
368 | DWORD fdwSupport)
|
---|
369 | {
|
---|
370 | struct MSACM_FormatEnumWtoA_Instance* pafei;
|
---|
371 |
|
---|
372 | pafei = (struct MSACM_FormatEnumWtoA_Instance*)dwInstance;
|
---|
373 |
|
---|
374 | pafei->pafda->dwFormatIndex = pafdw->dwFormatIndex;
|
---|
375 | pafei->pafda->dwFormatTag = pafdw->dwFormatTag;
|
---|
376 | pafei->pafda->fdwSupport = pafdw->fdwSupport;
|
---|
377 | WideCharToMultiByte( CP_ACP, 0, pafdw->szFormat, -1,
|
---|
378 | pafei->pafda->szFormat, sizeof(pafei->pafda->szFormat), NULL, NULL );
|
---|
379 |
|
---|
380 | return (pafei->fnCallback)(hadid, pafei->pafda,
|
---|
381 | pafei->dwInstance, fdwSupport);
|
---|
382 | }
|
---|
383 |
|
---|
384 | /***********************************************************************
|
---|
385 | * acmFormatEnumA (MSACM32.27)
|
---|
386 | */
|
---|
387 | MMRESULT WINAPI acmFormatEnumA(HACMDRIVER had, PACMFORMATDETAILSA pafda,
|
---|
388 | ACMFORMATENUMCBA fnCallback, DWORD dwInstance,
|
---|
389 | DWORD fdwEnum)
|
---|
390 | {
|
---|
391 | ACMFORMATDETAILSW afdw;
|
---|
392 | struct MSACM_FormatEnumWtoA_Instance afei;
|
---|
393 |
|
---|
394 | memset(&afdw, 0, sizeof(afdw));
|
---|
395 | afdw.cbStruct = sizeof(afdw);
|
---|
396 | afdw.dwFormatIndex = pafda->dwFormatIndex;
|
---|
397 | afdw.dwFormatTag = pafda->dwFormatTag;
|
---|
398 | afdw.pwfx = pafda->pwfx;
|
---|
399 | afdw.cbwfx = pafda->cbwfx;
|
---|
400 |
|
---|
401 | afei.pafda = pafda;
|
---|
402 | afei.dwInstance = dwInstance;
|
---|
403 | afei.fnCallback = fnCallback;
|
---|
404 |
|
---|
405 | return acmFormatEnumW(had, &afdw, MSACM_FormatEnumCallbackWtoA,
|
---|
406 | (DWORD)&afei, fdwEnum);
|
---|
407 | }
|
---|
408 |
|
---|
409 | /***********************************************************************
|
---|
410 | * acmFormatEnumW (MSACM32.28)
|
---|
411 | */
|
---|
412 | static BOOL MSACM_FormatEnumHelper(PWINE_ACMDRIVERID padid, HACMDRIVER had,
|
---|
413 | PACMFORMATDETAILSW pafd, PWAVEFORMATEX pwfxRef,
|
---|
414 | ACMFORMATENUMCBW fnCallback, DWORD dwInstance,
|
---|
415 | DWORD fdwEnum)
|
---|
416 | {
|
---|
417 | ACMDRIVERDETAILSW add;
|
---|
418 | ACMFORMATTAGDETAILSW aftd;
|
---|
419 | int i, j;
|
---|
420 |
|
---|
421 | add.cbStruct = sizeof(add);
|
---|
422 |
|
---|
423 | if (acmDriverDetailsW((HACMDRIVERID)padid, &add, 0) != MMSYSERR_NOERROR) return FALSE;
|
---|
424 |
|
---|
425 | for (i = 0; i < add.cFormatTags; i++) {
|
---|
426 | memset(&aftd, 0, sizeof(aftd));
|
---|
427 | aftd.cbStruct = sizeof(aftd);
|
---|
428 | aftd.dwFormatTagIndex = i;
|
---|
429 | if (acmFormatTagDetailsW(had, &aftd, ACM_FORMATTAGDETAILSF_INDEX) != MMSYSERR_NOERROR)
|
---|
430 | continue;
|
---|
431 |
|
---|
432 | if ((fdwEnum & ACM_FORMATENUMF_WFORMATTAG) && aftd.dwFormatTag != pwfxRef->wFormatTag)
|
---|
433 | continue;
|
---|
434 |
|
---|
435 | for (j = 0; j < aftd.cStandardFormats; j++) {
|
---|
436 | pafd->dwFormatIndex = j;
|
---|
437 | pafd->dwFormatTag = aftd.dwFormatTag;
|
---|
438 | if (acmFormatDetailsW(had, pafd, ACM_FORMATDETAILSF_INDEX) != MMSYSERR_NOERROR)
|
---|
439 | continue;
|
---|
440 |
|
---|
441 | if ((fdwEnum & ACM_FORMATENUMF_NCHANNELS) &&
|
---|
442 | pafd->pwfx->nChannels != pwfxRef->nChannels)
|
---|
443 | continue;
|
---|
444 | if ((fdwEnum & ACM_FORMATENUMF_NSAMPLESPERSEC) &&
|
---|
445 | pafd->pwfx->nSamplesPerSec != pwfxRef->nSamplesPerSec)
|
---|
446 | continue;
|
---|
447 | if ((fdwEnum & ACM_FORMATENUMF_WBITSPERSAMPLE) &&
|
---|
448 | pafd->pwfx->wBitsPerSample != pwfxRef->wBitsPerSample)
|
---|
449 | continue;
|
---|
450 | if ((fdwEnum & ACM_FORMATENUMF_HARDWARE) &&
|
---|
451 | !(pafd->fdwSupport & ACMDRIVERDETAILS_SUPPORTF_HARDWARE))
|
---|
452 | continue;
|
---|
453 |
|
---|
454 | /* more checks to be done on fdwEnum */
|
---|
455 |
|
---|
456 | if (!(fnCallback)((HACMDRIVERID)padid, pafd, dwInstance, add.fdwSupport))
|
---|
457 | return FALSE;
|
---|
458 | }
|
---|
459 | /* the "formats" used by the filters are also reported */
|
---|
460 | }
|
---|
461 | return TRUE;
|
---|
462 | }
|
---|
463 |
|
---|
464 | /**********************************************************************/
|
---|
465 |
|
---|
466 | MMRESULT WINAPI acmFormatEnumW(HACMDRIVER had, PACMFORMATDETAILSW pafd,
|
---|
467 | ACMFORMATENUMCBW fnCallback, DWORD dwInstance,
|
---|
468 | DWORD fdwEnum)
|
---|
469 | {
|
---|
470 | PWINE_ACMDRIVERID padid;
|
---|
471 | WAVEFORMATEX wfxRef;
|
---|
472 | BOOL ret;
|
---|
473 |
|
---|
474 | TRACE("(0x%08x, %p, %p, %ld, %ld)\n",
|
---|
475 | had, pafd, fnCallback, dwInstance, fdwEnum);
|
---|
476 |
|
---|
477 | if (pafd->cbStruct < sizeof(*pafd)) return MMSYSERR_INVALPARAM;
|
---|
478 |
|
---|
479 | if (fdwEnum & (ACM_FORMATENUMF_WFORMATTAG|ACM_FORMATENUMF_NCHANNELS|
|
---|
480 | ACM_FORMATENUMF_NSAMPLESPERSEC|ACM_FORMATENUMF_WBITSPERSAMPLE|
|
---|
481 | ACM_FORMATENUMF_CONVERT|ACM_FORMATENUMF_SUGGEST))
|
---|
482 | wfxRef = *pafd->pwfx;
|
---|
483 |
|
---|
484 | if ((fdwEnum & ACM_FORMATENUMF_HARDWARE) &&
|
---|
485 | !(fdwEnum & (ACM_FORMATENUMF_INPUT|ACM_FORMATENUMF_OUTPUT)))
|
---|
486 | return MMSYSERR_INVALPARAM;
|
---|
487 |
|
---|
488 | if ((fdwEnum & ACM_FORMATENUMF_WFORMATTAG) &&
|
---|
489 | (pafd->dwFormatTag != pafd->pwfx->wFormatTag))
|
---|
490 | return MMSYSERR_INVALPARAM;
|
---|
491 |
|
---|
492 | if (fdwEnum & (ACM_FORMATENUMF_CONVERT|ACM_FORMATENUMF_SUGGEST|
|
---|
493 | ACM_FORMATENUMF_INPUT|ACM_FORMATENUMF_OUTPUT))
|
---|
494 | FIXME("Unsupported fdwEnum values %08lx\n", fdwEnum);
|
---|
495 |
|
---|
496 | if (had) {
|
---|
497 | HACMDRIVERID hadid;
|
---|
498 |
|
---|
499 | if (acmDriverID(had, &hadid, 0) != MMSYSERR_NOERROR)
|
---|
500 | return MMSYSERR_INVALHANDLE;
|
---|
501 | MSACM_FormatEnumHelper(MSACM_GetDriverID(hadid), had, pafd, &wfxRef,
|
---|
502 | fnCallback, dwInstance, fdwEnum);
|
---|
503 | return MMSYSERR_NOERROR;
|
---|
504 | }
|
---|
505 | for (padid = MSACM_pFirstACMDriverID; padid; padid = padid->pNextACMDriverID) {
|
---|
506 | /* should check for codec only */
|
---|
507 | if (!padid->bEnabled || acmDriverOpen(&had, (HACMDRIVERID)padid, 0) != MMSYSERR_NOERROR)
|
---|
508 | continue;
|
---|
509 | ret = MSACM_FormatEnumHelper(padid, had, pafd, &wfxRef,
|
---|
510 | fnCallback, dwInstance, fdwEnum);
|
---|
511 | acmDriverClose(had, 0);
|
---|
512 | if (!ret) break;
|
---|
513 | }
|
---|
514 | return MMSYSERR_NOERROR;
|
---|
515 | }
|
---|
516 |
|
---|
517 | /***********************************************************************
|
---|
518 | * acmFormatSuggest (MSACM32.29)
|
---|
519 | */
|
---|
520 | MMRESULT WINAPI acmFormatSuggest(HACMDRIVER had, PWAVEFORMATEX pwfxSrc,
|
---|
521 | PWAVEFORMATEX pwfxDst, DWORD cbwfxDst, DWORD fdwSuggest)
|
---|
522 | {
|
---|
523 | ACMDRVFORMATSUGGEST adfg;
|
---|
524 | MMRESULT mmr;
|
---|
525 |
|
---|
526 | TRACE("(0x%08x, %p, %p, %ld, %ld)\n",
|
---|
527 | had, pwfxSrc, pwfxDst, cbwfxDst, fdwSuggest);
|
---|
528 |
|
---|
529 | if (fdwSuggest & ~(ACM_FORMATSUGGESTF_NCHANNELS|ACM_FORMATSUGGESTF_NSAMPLESPERSEC|
|
---|
530 | ACM_FORMATSUGGESTF_WBITSPERSAMPLE|ACM_FORMATSUGGESTF_WFORMATTAG))
|
---|
531 | return MMSYSERR_INVALFLAG;
|
---|
532 |
|
---|
533 | adfg.cbStruct = sizeof(adfg);
|
---|
534 | adfg.fdwSuggest = fdwSuggest;
|
---|
535 | adfg.pwfxSrc = pwfxSrc;
|
---|
536 | adfg.cbwfxSrc = (pwfxSrc->wFormatTag == WAVE_FORMAT_PCM) ?
|
---|
537 | sizeof(WAVEFORMATEX) : pwfxSrc->cbSize;
|
---|
538 | adfg.pwfxDst = pwfxDst;
|
---|
539 | adfg.cbwfxDst = cbwfxDst;
|
---|
540 |
|
---|
541 | if (had == (HACMDRIVER)NULL) {
|
---|
542 | PWINE_ACMDRIVERID padid;
|
---|
543 |
|
---|
544 | /* MS doc says: ACM finds the best suggestion.
|
---|
545 | * Well, first found will be the "best"
|
---|
546 | */
|
---|
547 | mmr = ACMERR_NOTPOSSIBLE;
|
---|
548 | for (padid = MSACM_pFirstACMDriverID; padid; padid = padid->pNextACMDriverID) {
|
---|
549 | /* should check for codec only */
|
---|
550 | if (!padid->bEnabled ||
|
---|
551 | acmDriverOpen(&had, (HACMDRIVERID)padid, 0) != MMSYSERR_NOERROR)
|
---|
552 | continue;
|
---|
553 |
|
---|
554 | if (MSACM_Message(had, ACMDM_FORMAT_SUGGEST,
|
---|
555 | (LPARAM)&adfg, 0L) == MMSYSERR_NOERROR) {
|
---|
556 | mmr = MMSYSERR_NOERROR;
|
---|
557 | break;
|
---|
558 | }
|
---|
559 | acmDriverClose(had, 0);
|
---|
560 | }
|
---|
561 | } else {
|
---|
562 | mmr = MSACM_Message(had, ACMDM_FORMAT_SUGGEST, (LPARAM)&adfg, 0L);
|
---|
563 | }
|
---|
564 | return mmr;
|
---|
565 | }
|
---|
566 |
|
---|
567 | /***********************************************************************
|
---|
568 | * acmFormatTagDetailsA (MSACM32.30)
|
---|
569 | */
|
---|
570 | MMRESULT WINAPI acmFormatTagDetailsA(HACMDRIVER had, PACMFORMATTAGDETAILSA paftda,
|
---|
571 | DWORD fdwDetails)
|
---|
572 | {
|
---|
573 | ACMFORMATTAGDETAILSW aftdw;
|
---|
574 | MMRESULT mmr;
|
---|
575 |
|
---|
576 | memset(&aftdw, 0, sizeof(aftdw));
|
---|
577 | aftdw.cbStruct = sizeof(aftdw);
|
---|
578 | aftdw.dwFormatTagIndex = paftda->dwFormatTagIndex;
|
---|
579 | aftdw.dwFormatTag = paftda->dwFormatTag;
|
---|
580 |
|
---|
581 | mmr = acmFormatTagDetailsW(had, &aftdw, fdwDetails);
|
---|
582 | if (mmr == MMSYSERR_NOERROR) {
|
---|
583 | paftda->dwFormatTag = aftdw.dwFormatTag;
|
---|
584 | paftda->dwFormatTagIndex = aftdw.dwFormatTagIndex;
|
---|
585 | paftda->cbFormatSize = aftdw.cbFormatSize;
|
---|
586 | paftda->fdwSupport = aftdw.fdwSupport;
|
---|
587 | paftda->cStandardFormats = aftdw.cStandardFormats;
|
---|
588 | WideCharToMultiByte( CP_ACP, 0, aftdw.szFormatTag, -1, paftda->szFormatTag,
|
---|
589 | sizeof(paftda->szFormatTag), NULL, NULL );
|
---|
590 | }
|
---|
591 | return mmr;
|
---|
592 | }
|
---|
593 |
|
---|
594 | /***********************************************************************
|
---|
595 | * acmFormatTagDetailsW (MSACM32.31)
|
---|
596 | */
|
---|
597 | MMRESULT WINAPI acmFormatTagDetailsW(HACMDRIVER had, PACMFORMATTAGDETAILSW paftd,
|
---|
598 | DWORD fdwDetails)
|
---|
599 | {
|
---|
600 | PWINE_ACMDRIVERID padid;
|
---|
601 | MMRESULT mmr;
|
---|
602 |
|
---|
603 | TRACE("(0x%08x, %p, %ld)\n", had, paftd, fdwDetails);
|
---|
604 |
|
---|
605 | if (fdwDetails & ~(ACM_FORMATTAGDETAILSF_FORMATTAG|ACM_FORMATTAGDETAILSF_INDEX|
|
---|
606 | ACM_FORMATTAGDETAILSF_LARGESTSIZE))
|
---|
607 | return MMSYSERR_INVALFLAG;
|
---|
608 |
|
---|
609 | switch (fdwDetails) {
|
---|
610 | case ACM_FORMATTAGDETAILSF_FORMATTAG:
|
---|
611 | if (had == (HACMDRIVER)NULL) {
|
---|
612 | mmr = ACMERR_NOTPOSSIBLE;
|
---|
613 | for (padid = MSACM_pFirstACMDriverID; padid; padid = padid->pNextACMDriverID) {
|
---|
614 | /* should check for codec only */
|
---|
615 | if (padid->bEnabled && acmDriverOpen(&had, (HACMDRIVERID)padid, 0) == 0) {
|
---|
616 | mmr = MSACM_Message(had, ACMDM_FORMATTAG_DETAILS,
|
---|
617 | (LPARAM)paftd, (LPARAM)fdwDetails);
|
---|
618 | acmDriverClose(had, 0);
|
---|
619 | if (mmr == MMSYSERR_NOERROR) break;
|
---|
620 | }
|
---|
621 | }
|
---|
622 | } else {
|
---|
623 | mmr = MSACM_Message(had, ACMDM_FORMATTAG_DETAILS,
|
---|
624 | (LPARAM)paftd, (LPARAM)fdwDetails);
|
---|
625 | }
|
---|
626 | break;
|
---|
627 |
|
---|
628 | case ACM_FORMATTAGDETAILSF_INDEX:
|
---|
629 | /* FIXME should check paftd->dwFormatTagIndex < add.cFormatTags */
|
---|
630 | mmr = MSACM_Message(had, ACMDM_FORMATTAG_DETAILS,
|
---|
631 | (LPARAM)paftd, (LPARAM)fdwDetails);
|
---|
632 | break;
|
---|
633 |
|
---|
634 | case ACM_FORMATTAGDETAILSF_LARGESTSIZE:
|
---|
635 | if (had == (HACMDRIVER)NULL) {
|
---|
636 | ACMFORMATTAGDETAILSW tmp;
|
---|
637 | DWORD ft = paftd->dwFormatTag;
|
---|
638 |
|
---|
639 | mmr = ACMERR_NOTPOSSIBLE;
|
---|
640 | for (padid = MSACM_pFirstACMDriverID; padid; padid = padid->pNextACMDriverID) {
|
---|
641 | /* should check for codec only */
|
---|
642 | if (padid->bEnabled &&
|
---|
643 | acmDriverOpen(&had, (HACMDRIVERID)padid, 0) == 0) {
|
---|
644 |
|
---|
645 | memset(&tmp, 0, sizeof(tmp));
|
---|
646 | tmp.cbStruct = sizeof(tmp);
|
---|
647 | tmp.dwFormatTag = ft;
|
---|
648 |
|
---|
649 | if (MSACM_Message(had, ACMDM_FORMATTAG_DETAILS,
|
---|
650 | (LPARAM)&tmp,
|
---|
651 | (LPARAM)fdwDetails) == MMSYSERR_NOERROR) {
|
---|
652 | if (mmr == ACMERR_NOTPOSSIBLE ||
|
---|
653 | paftd->cbFormatSize < tmp.cbFormatSize) {
|
---|
654 | *paftd = tmp;
|
---|
655 | mmr = MMSYSERR_NOERROR;
|
---|
656 | }
|
---|
657 | }
|
---|
658 | acmDriverClose(had, 0);
|
---|
659 | }
|
---|
660 | }
|
---|
661 | } else {
|
---|
662 | mmr = MSACM_Message(had, ACMDM_FORMATTAG_DETAILS,
|
---|
663 | (LPARAM)paftd, (LPARAM)fdwDetails);
|
---|
664 | }
|
---|
665 | break;
|
---|
666 |
|
---|
667 | default:
|
---|
668 | WARN("Unsupported fdwDetails=%08lx\n", fdwDetails);
|
---|
669 | mmr = MMSYSERR_ERROR;
|
---|
670 | }
|
---|
671 |
|
---|
672 | if (mmr == MMSYSERR_NOERROR &&
|
---|
673 | paftd->dwFormatTag == WAVE_FORMAT_PCM && paftd->szFormatTag[0] == 0)
|
---|
674 | MultiByteToWideChar( CP_ACP, 0, "PCM", -1, paftd->szFormatTag,
|
---|
675 | sizeof(paftd->szFormatTag)/sizeof(WCHAR) );
|
---|
676 |
|
---|
677 | return mmr;
|
---|
678 | }
|
---|
679 |
|
---|
680 | struct MSACM_FormatTagEnumWtoA_Instance {
|
---|
681 | PACMFORMATTAGDETAILSA paftda;
|
---|
682 | DWORD dwInstance;
|
---|
683 | ACMFORMATTAGENUMCBA fnCallback;
|
---|
684 | };
|
---|
685 |
|
---|
686 | static BOOL CALLBACK MSACM_FormatTagEnumCallbackWtoA(HACMDRIVERID hadid,
|
---|
687 | PACMFORMATTAGDETAILSW paftdw,
|
---|
688 | DWORD dwInstance,
|
---|
689 | DWORD fdwSupport)
|
---|
690 | {
|
---|
691 | struct MSACM_FormatTagEnumWtoA_Instance* paftei;
|
---|
692 |
|
---|
693 | paftei = (struct MSACM_FormatTagEnumWtoA_Instance*)dwInstance;
|
---|
694 |
|
---|
695 | paftei->paftda->dwFormatTagIndex = paftdw->dwFormatTagIndex;
|
---|
696 | paftei->paftda->dwFormatTag = paftdw->dwFormatTag;
|
---|
697 | paftei->paftda->cbFormatSize = paftdw->cbFormatSize;
|
---|
698 | paftei->paftda->fdwSupport = paftdw->fdwSupport;
|
---|
699 | paftei->paftda->cStandardFormats = paftdw->cStandardFormats;
|
---|
700 | WideCharToMultiByte( CP_ACP, 0, paftdw->szFormatTag, -1, paftei->paftda->szFormatTag,
|
---|
701 | sizeof(paftei->paftda->szFormatTag), NULL, NULL );
|
---|
702 |
|
---|
703 | return (paftei->fnCallback)(hadid, paftei->paftda,
|
---|
704 | paftei->dwInstance, fdwSupport);
|
---|
705 | }
|
---|
706 |
|
---|
707 | /***********************************************************************
|
---|
708 | * acmFormatTagEnumA (MSACM32.32)
|
---|
709 | */
|
---|
710 | MMRESULT WINAPI acmFormatTagEnumA(HACMDRIVER had, PACMFORMATTAGDETAILSA paftda,
|
---|
711 | ACMFORMATTAGENUMCBA fnCallback, DWORD dwInstance,
|
---|
712 | DWORD fdwEnum)
|
---|
713 | {
|
---|
714 | ACMFORMATTAGDETAILSW aftdw;
|
---|
715 | struct MSACM_FormatTagEnumWtoA_Instance aftei;
|
---|
716 |
|
---|
717 | memset(&aftdw, 0, sizeof(aftdw));
|
---|
718 | aftdw.cbStruct = sizeof(aftdw);
|
---|
719 | aftdw.dwFormatTagIndex = paftda->dwFormatTagIndex;
|
---|
720 | aftdw.dwFormatTag = paftda->dwFormatTag;
|
---|
721 |
|
---|
722 | aftei.paftda = paftda;
|
---|
723 | aftei.dwInstance = dwInstance;
|
---|
724 | aftei.fnCallback = fnCallback;
|
---|
725 |
|
---|
726 | return acmFormatTagEnumW(had, &aftdw, MSACM_FormatTagEnumCallbackWtoA,
|
---|
727 | (DWORD)&aftei, fdwEnum);
|
---|
728 | }
|
---|
729 |
|
---|
730 | /***********************************************************************
|
---|
731 | * acmFormatTagEnumW (MSACM32.33)
|
---|
732 | */
|
---|
733 | MMRESULT WINAPI acmFormatTagEnumW(HACMDRIVER had, PACMFORMATTAGDETAILSW paftd,
|
---|
734 | ACMFORMATTAGENUMCBW fnCallback, DWORD dwInstance,
|
---|
735 | DWORD fdwEnum)
|
---|
736 | {
|
---|
737 | PWINE_ACMDRIVERID padid;
|
---|
738 | ACMDRIVERDETAILSW add;
|
---|
739 | int i;
|
---|
740 | BOOL bPcmDone = FALSE;
|
---|
741 |
|
---|
742 | TRACE("(0x%08x, %p, %p, %ld, %ld)\n",
|
---|
743 | had, paftd, fnCallback, dwInstance, fdwEnum);
|
---|
744 |
|
---|
745 | if (paftd->cbStruct < sizeof(*paftd)) return MMSYSERR_INVALPARAM;
|
---|
746 |
|
---|
747 | if (had) FIXME("had != NULL, not supported\n");
|
---|
748 |
|
---|
749 | for (padid = MSACM_pFirstACMDriverID; padid; padid = padid->pNextACMDriverID) {
|
---|
750 | /* should check for codec only */
|
---|
751 | if (padid->bEnabled && acmDriverOpen(&had, (HACMDRIVERID)padid, 0) == MMSYSERR_NOERROR) {
|
---|
752 | add.cbStruct = sizeof(add);
|
---|
753 |
|
---|
754 | if (acmDriverDetailsW((HACMDRIVERID)padid, &add, 0) == MMSYSERR_NOERROR) {
|
---|
755 | for (i = 0; i < add.cFormatTags; i++) {
|
---|
756 | paftd->dwFormatTagIndex = i;
|
---|
757 | if (acmFormatTagDetailsW(had, paftd, ACM_FORMATTAGDETAILSF_INDEX) == MMSYSERR_NOERROR) {
|
---|
758 | if (paftd->dwFormatTag == WAVE_FORMAT_PCM) {
|
---|
759 | /* FIXME (EPP): I'm not sure this is the correct
|
---|
760 | * algorithm (should make more sense to apply the same
|
---|
761 | * for all already loaded formats, but this will do
|
---|
762 | * for now
|
---|
763 | */
|
---|
764 | if (bPcmDone) continue;
|
---|
765 | bPcmDone = TRUE;
|
---|
766 | }
|
---|
767 | if (!(fnCallback)((HACMDRIVERID)padid, paftd, dwInstance,
|
---|
768 | add.fdwSupport)) {
|
---|
769 | padid = NULL;
|
---|
770 | break;
|
---|
771 | }
|
---|
772 | }
|
---|
773 | }
|
---|
774 | }
|
---|
775 | }
|
---|
776 | acmDriverClose(had, 0);
|
---|
777 | }
|
---|
778 | return MMSYSERR_NOERROR;
|
---|
779 | }
|
---|