Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenformat.c
Go to the documentation of this file.
00001 /* -*- tab-width: 8; c-basic-offset: 4 -*- */ 00002 00003 /* 00004 * MSACM32 library 00005 * 00006 * Copyright 1998 Patrik Stridvall 00007 * 2000 Eric Pouech 00008 * 00009 * This library is free software; you can redistribute it and/or 00010 * modify it under the terms of the GNU Lesser General Public 00011 * License as published by the Free Software Foundation; either 00012 * version 2.1 of the License, or (at your option) any later version. 00013 * 00014 * This library is distributed in the hope that it will be useful, 00015 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00016 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00017 * Lesser General Public License for more details. 00018 * 00019 * You should have received a copy of the GNU Lesser General Public 00020 * License along with this library; if not, write to the Free Software 00021 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 00022 */ 00023 00024 #include <stdarg.h> 00025 #include <string.h> 00026 #include "windef.h" 00027 #include "winbase.h" 00028 #include "winnls.h" 00029 #include "winerror.h" 00030 #include "wingdi.h" 00031 #include "winuser.h" 00032 #include "wine/unicode.h" 00033 #include "wine/debug.h" 00034 #include "mmsystem.h" 00035 #include "mmreg.h" 00036 #include "msacm.h" 00037 #include "msacmdrv.h" 00038 #include "wineacm.h" 00039 00040 WINE_DEFAULT_DEBUG_CHANNEL(msacm); 00041 00042 static PACMFORMATCHOOSEA afc; 00043 00044 struct MSACM_FillFormatData { 00045 HWND hWnd; 00046 #define WINE_ACMFF_TAG 0 00047 #define WINE_ACMFF_FORMAT 1 00048 #define WINE_ACMFF_WFX 2 00049 int mode; 00050 char szFormatTag[ACMFORMATTAGDETAILS_FORMATTAG_CHARS]; 00051 PACMFORMATCHOOSEA afc; 00052 DWORD ret; 00053 }; 00054 00055 static BOOL CALLBACK MSACM_FillFormatTagsCB(HACMDRIVERID hadid, 00056 PACMFORMATTAGDETAILSA paftd, 00057 DWORD_PTR dwInstance, 00058 DWORD fdwSupport) 00059 { 00060 struct MSACM_FillFormatData* affd = (struct MSACM_FillFormatData*)dwInstance; 00061 00062 switch (affd->mode) { 00063 case WINE_ACMFF_TAG: 00064 if (SendDlgItemMessageA(affd->hWnd, IDD_ACMFORMATCHOOSE_CMB_FORMATTAG, 00065 CB_FINDSTRINGEXACT, -1, 00066 (LPARAM)paftd->szFormatTag) == CB_ERR) 00067 SendDlgItemMessageA(affd->hWnd, IDD_ACMFORMATCHOOSE_CMB_FORMATTAG, 00068 CB_ADDSTRING, 0, (LPARAM)paftd->szFormatTag); 00069 break; 00070 case WINE_ACMFF_FORMAT: 00071 if (strcmp(affd->szFormatTag, paftd->szFormatTag) == 0) { 00072 HACMDRIVER had; 00073 00074 if (acmDriverOpen(&had, hadid, 0) == MMSYSERR_NOERROR) { 00075 ACMFORMATDETAILSA afd; 00076 unsigned int i, len; 00077 MMRESULT mmr; 00078 char buffer[ACMFORMATDETAILS_FORMAT_CHARS+16]; 00079 00080 afd.cbStruct = sizeof(afd); 00081 afd.dwFormatTag = paftd->dwFormatTag; 00082 afd.pwfx = HeapAlloc(MSACM_hHeap, 0, paftd->cbFormatSize); 00083 if (!afd.pwfx) return FALSE; 00084 afd.pwfx->wFormatTag = paftd->dwFormatTag; 00085 afd.pwfx->cbSize = paftd->cbFormatSize; 00086 afd.cbwfx = paftd->cbFormatSize; 00087 00088 for (i = 0; i < paftd->cStandardFormats; i++) { 00089 afd.dwFormatIndex = i; 00090 mmr = acmFormatDetailsA(had, &afd, ACM_FORMATDETAILSF_INDEX); 00091 if (mmr == MMSYSERR_NOERROR) { 00092 lstrcpynA(buffer, afd.szFormat, ACMFORMATTAGDETAILS_FORMATTAG_CHARS + 1); 00093 len = strlen(buffer); 00094 memset(buffer+len, ' ', ACMFORMATTAGDETAILS_FORMATTAG_CHARS - len); 00095 wsprintfA(buffer + ACMFORMATTAGDETAILS_FORMATTAG_CHARS, 00096 "%d Ko/s", 00097 (afd.pwfx->nAvgBytesPerSec + 512) / 1024); 00098 SendDlgItemMessageA(affd->hWnd, 00099 IDD_ACMFORMATCHOOSE_CMB_FORMAT, 00100 CB_ADDSTRING, 0, (LPARAM)buffer); 00101 } 00102 } 00103 acmDriverClose(had, 0); 00104 SendDlgItemMessageA(affd->hWnd, IDD_ACMFORMATCHOOSE_CMB_FORMAT, 00105 CB_SETCURSEL, 0, 0); 00106 HeapFree(MSACM_hHeap, 0, afd.pwfx); 00107 } 00108 } 00109 break; 00110 case WINE_ACMFF_WFX: 00111 if (strcmp(affd->szFormatTag, paftd->szFormatTag) == 0) { 00112 HACMDRIVER had; 00113 00114 if (acmDriverOpen(&had, hadid, 0) == MMSYSERR_NOERROR) { 00115 ACMFORMATDETAILSA afd; 00116 00117 afd.cbStruct = sizeof(afd); 00118 afd.dwFormatTag = paftd->dwFormatTag; 00119 afd.pwfx = affd->afc->pwfx; 00120 afd.cbwfx = affd->afc->cbwfx; 00121 00122 afd.dwFormatIndex = SendDlgItemMessageA(affd->hWnd, IDD_ACMFORMATCHOOSE_CMB_FORMAT, 00123 CB_GETCURSEL, 0, 0); 00124 affd->ret = acmFormatDetailsA(had, &afd, ACM_FORMATDETAILSF_INDEX); 00125 acmDriverClose(had, 0); 00126 return TRUE; 00127 } 00128 } 00129 break; 00130 default: 00131 FIXME("Unknown mode (%d)\n", affd->mode); 00132 break; 00133 } 00134 return TRUE; 00135 } 00136 00137 static BOOL MSACM_FillFormatTags(HWND hWnd) 00138 { 00139 ACMFORMATTAGDETAILSA aftd; 00140 struct MSACM_FillFormatData affd; 00141 00142 memset(&aftd, 0, sizeof(aftd)); 00143 aftd.cbStruct = sizeof(aftd); 00144 00145 affd.hWnd = hWnd; 00146 affd.mode = WINE_ACMFF_TAG; 00147 00148 acmFormatTagEnumA(NULL, &aftd, MSACM_FillFormatTagsCB, (DWORD_PTR)&affd, 0); 00149 SendDlgItemMessageA(hWnd, IDD_ACMFORMATCHOOSE_CMB_FORMATTAG, CB_SETCURSEL, 0, 0); 00150 return TRUE; 00151 } 00152 00153 static BOOL MSACM_FillFormat(HWND hWnd) 00154 { 00155 ACMFORMATTAGDETAILSA aftd; 00156 struct MSACM_FillFormatData affd; 00157 00158 SendDlgItemMessageA(hWnd, IDD_ACMFORMATCHOOSE_CMB_FORMAT, CB_RESETCONTENT, 0, 0); 00159 00160 memset(&aftd, 0, sizeof(aftd)); 00161 aftd.cbStruct = sizeof(aftd); 00162 00163 affd.hWnd = hWnd; 00164 affd.mode = WINE_ACMFF_FORMAT; 00165 SendDlgItemMessageA(hWnd, IDD_ACMFORMATCHOOSE_CMB_FORMATTAG, 00166 CB_GETLBTEXT, 00167 SendDlgItemMessageA(hWnd, IDD_ACMFORMATCHOOSE_CMB_FORMATTAG, 00168 CB_GETCURSEL, 0, 0), 00169 (LPARAM)affd.szFormatTag); 00170 00171 acmFormatTagEnumA(NULL, &aftd, MSACM_FillFormatTagsCB, (DWORD_PTR)&affd, 0); 00172 SendDlgItemMessageA(hWnd, IDD_ACMFORMATCHOOSE_CMB_FORMAT, CB_SETCURSEL, 0, 0); 00173 return TRUE; 00174 } 00175 00176 static MMRESULT MSACM_GetWFX(HWND hWnd, PACMFORMATCHOOSEA afc) 00177 { 00178 ACMFORMATTAGDETAILSA aftd; 00179 struct MSACM_FillFormatData affd; 00180 00181 memset(&aftd, 0, sizeof(aftd)); 00182 aftd.cbStruct = sizeof(aftd); 00183 00184 affd.hWnd = hWnd; 00185 affd.mode = WINE_ACMFF_WFX; 00186 affd.afc = afc; 00187 affd.ret = MMSYSERR_NOERROR; 00188 SendDlgItemMessageA(hWnd, IDD_ACMFORMATCHOOSE_CMB_FORMATTAG, 00189 CB_GETLBTEXT, 00190 SendDlgItemMessageA(hWnd, IDD_ACMFORMATCHOOSE_CMB_FORMATTAG, 00191 CB_GETCURSEL, 0, 0), 00192 (LPARAM)affd.szFormatTag); 00193 00194 acmFormatTagEnumA(NULL, &aftd, MSACM_FillFormatTagsCB, (DWORD_PTR)&affd, 0); 00195 return affd.ret; 00196 } 00197 00198 static INT_PTR CALLBACK FormatChooseDlgProc(HWND hWnd, UINT msg, 00199 WPARAM wParam, LPARAM lParam) 00200 { 00201 00202 TRACE("hwnd=%p msg=%i 0x%08lx 0x%08lx\n", hWnd, msg, wParam, lParam ); 00203 00204 switch (msg) { 00205 case WM_INITDIALOG: 00206 afc = (PACMFORMATCHOOSEA)lParam; 00207 MSACM_FillFormatTags(hWnd); 00208 MSACM_FillFormat(hWnd); 00209 if ((afc->fdwStyle & ~(ACMFORMATCHOOSE_STYLEF_CONTEXTHELP| 00210 ACMFORMATCHOOSE_STYLEF_SHOWHELP)) != 0) 00211 FIXME("Unsupported style %08x\n", ((PACMFORMATCHOOSEA)lParam)->fdwStyle); 00212 if (!(afc->fdwStyle & ACMFORMATCHOOSE_STYLEF_SHOWHELP)) 00213 ShowWindow(GetDlgItem(hWnd, IDD_ACMFORMATCHOOSE_BTN_HELP), SW_HIDE); 00214 return TRUE; 00215 00216 case WM_COMMAND: 00217 switch (LOWORD(wParam)) { 00218 case IDOK: 00219 EndDialog(hWnd, MSACM_GetWFX(hWnd, afc)); 00220 return TRUE; 00221 case IDCANCEL: 00222 EndDialog(hWnd, ACMERR_CANCELED); 00223 return TRUE; 00224 case IDD_ACMFORMATCHOOSE_CMB_FORMATTAG: 00225 switch (HIWORD(wParam)) { 00226 case CBN_SELCHANGE: 00227 MSACM_FillFormat(hWnd); 00228 break; 00229 default: 00230 TRACE("Dropped dlgNotif (fmtTag): 0x%08x 0x%08lx\n", 00231 HIWORD(wParam), lParam); 00232 break; 00233 } 00234 break; 00235 case IDD_ACMFORMATCHOOSE_BTN_HELP: 00236 if (afc->fdwStyle & ACMFORMATCHOOSE_STYLEF_SHOWHELP) 00237 SendMessageA(afc->hwndOwner, 00238 RegisterWindowMessageA(ACMHELPMSGSTRINGA), 0L, 0L); 00239 break; 00240 00241 default: 00242 TRACE("Dropped dlgCmd: ctl=%d ntf=0x%04x 0x%08lx\n", 00243 LOWORD(wParam), HIWORD(wParam), lParam); 00244 break; 00245 } 00246 break; 00247 case WM_CONTEXTMENU: 00248 if (afc->fdwStyle & ACMFORMATCHOOSE_STYLEF_CONTEXTHELP) 00249 SendMessageA(afc->hwndOwner, 00250 RegisterWindowMessageA(ACMHELPMSGCONTEXTMENUA), 00251 wParam, lParam); 00252 break; 00253 #if defined(WM_CONTEXTHELP) 00254 case WM_CONTEXTHELP: 00255 if (afc->fdwStyle & ACMFORMATCHOOSE_STYLEF_CONTEXTHELP) 00256 SendMessageA(afc->hwndOwner, 00257 RegisterWindowMessageA(ACMHELPMSGCONTEXTHELPA), 00258 wParam, lParam); 00259 break; 00260 #endif 00261 default: 00262 TRACE("Dropped dlgMsg: hwnd=%p msg=%i 0x%08lx 0x%08lx\n", 00263 hWnd, msg, wParam, lParam ); 00264 break; 00265 } 00266 return FALSE; 00267 } 00268 00269 /*********************************************************************** 00270 * acmFormatChooseA (MSACM32.@) 00271 */ 00272 MMRESULT WINAPI acmFormatChooseA(PACMFORMATCHOOSEA pafmtc) 00273 { 00274 return DialogBoxParamA(MSACM_hInstance32, MAKEINTRESOURCEA(DLG_ACMFORMATCHOOSE_ID), 00275 pafmtc->hwndOwner, FormatChooseDlgProc, (LPARAM)pafmtc); 00276 } 00277 00278 /*********************************************************************** 00279 * acmFormatChooseW (MSACM32.@) 00280 */ 00281 MMRESULT WINAPI acmFormatChooseW(PACMFORMATCHOOSEW pafmtc) 00282 { 00283 FIXME("(%p): stub\n", pafmtc); 00284 SetLastError(ERROR_CALL_NOT_IMPLEMENTED); 00285 return MMSYSERR_ERROR; 00286 } 00287 00288 /*********************************************************************** 00289 * acmFormatDetailsA (MSACM32.@) 00290 */ 00291 MMRESULT WINAPI acmFormatDetailsA(HACMDRIVER had, PACMFORMATDETAILSA pafd, 00292 DWORD fdwDetails) 00293 { 00294 ACMFORMATDETAILSW afdw; 00295 MMRESULT mmr; 00296 00297 memset(&afdw, 0, sizeof(afdw)); 00298 afdw.cbStruct = sizeof(afdw); 00299 afdw.dwFormatIndex = pafd->dwFormatIndex; 00300 afdw.dwFormatTag = pafd->dwFormatTag; 00301 afdw.pwfx = pafd->pwfx; 00302 afdw.cbwfx = pafd->cbwfx; 00303 00304 mmr = acmFormatDetailsW(had, &afdw, fdwDetails); 00305 if (mmr == MMSYSERR_NOERROR) { 00306 pafd->dwFormatTag = afdw.dwFormatTag; 00307 pafd->fdwSupport = afdw.fdwSupport; 00308 WideCharToMultiByte( CP_ACP, 0, afdw.szFormat, -1, 00309 pafd->szFormat, sizeof(pafd->szFormat), NULL, NULL ); 00310 } 00311 return mmr; 00312 } 00313 00314 /*********************************************************************** 00315 * acmFormatDetailsW (MSACM32.@) 00316 */ 00317 MMRESULT WINAPI acmFormatDetailsW(HACMDRIVER had, PACMFORMATDETAILSW pafd, DWORD fdwDetails) 00318 { 00319 MMRESULT mmr; 00320 static const WCHAR fmt1[] = {'%','d',' ','H','z',0}; 00321 static const WCHAR fmt2[] = {';',' ','%','d',' ','b','i','t','s',0}; 00322 ACMFORMATTAGDETAILSA aftd; 00323 00324 TRACE("(%p, %p, %d)\n", had, pafd, fdwDetails); 00325 00326 memset(&aftd, 0, sizeof(aftd)); 00327 aftd.cbStruct = sizeof(aftd); 00328 00329 if (pafd->cbStruct < sizeof(*pafd)) return MMSYSERR_INVALPARAM; 00330 00331 switch (fdwDetails) { 00332 case ACM_FORMATDETAILSF_FORMAT: 00333 if (pafd->dwFormatTag != pafd->pwfx->wFormatTag) { 00334 mmr = MMSYSERR_INVALPARAM; 00335 break; 00336 } 00337 if (had == NULL) { 00338 PWINE_ACMDRIVERID padid; 00339 00340 mmr = ACMERR_NOTPOSSIBLE; 00341 for (padid = MSACM_pFirstACMDriverID; padid; padid = padid->pNextACMDriverID) { 00342 /* should check for codec only */ 00343 if (!(padid->fdwSupport & ACMDRIVERDETAILS_SUPPORTF_DISABLED) && 00344 acmDriverOpen(&had, (HACMDRIVERID)padid, 0) == 0) { 00345 mmr = MSACM_Message(had, ACMDM_FORMAT_DETAILS, (LPARAM)pafd, fdwDetails); 00346 acmDriverClose(had, 0); 00347 if (mmr == MMSYSERR_NOERROR) break; 00348 } 00349 } 00350 } else { 00351 mmr = MSACM_Message(had, ACMDM_FORMAT_DETAILS, (LPARAM)pafd, fdwDetails); 00352 } 00353 break; 00354 case ACM_FORMATDETAILSF_INDEX: 00355 /* should check pafd->dwFormatIndex < aftd->cStandardFormats */ 00356 mmr = MSACM_Message(had, ACMDM_FORMAT_DETAILS, (LPARAM)pafd, fdwDetails); 00357 break; 00358 default: 00359 WARN("Unknown fdwDetails %08x\n", fdwDetails); 00360 mmr = MMSYSERR_INVALFLAG; 00361 break; 00362 } 00363 00364 if (mmr == MMSYSERR_NOERROR && pafd->szFormat[0] == 0) { 00365 wsprintfW(pafd->szFormat, fmt1, pafd->pwfx->nSamplesPerSec); 00366 if (pafd->pwfx->wBitsPerSample) { 00367 wsprintfW(pafd->szFormat + lstrlenW(pafd->szFormat), fmt2, 00368 pafd->pwfx->wBitsPerSample); 00369 } 00370 MultiByteToWideChar( CP_ACP, 0, (pafd->pwfx->nChannels == 1) ? "; Mono" : "; Stereo", -1, 00371 pafd->szFormat + strlenW(pafd->szFormat), 00372 sizeof(pafd->szFormat)/sizeof(WCHAR) - strlenW(pafd->szFormat) ); 00373 } 00374 00375 TRACE("=> %d\n", mmr); 00376 return mmr; 00377 } 00378 00379 struct MSACM_FormatEnumWtoA_Instance { 00380 PACMFORMATDETAILSA pafda; 00381 DWORD_PTR dwInstance; 00382 ACMFORMATENUMCBA fnCallback; 00383 }; 00384 00385 static BOOL CALLBACK MSACM_FormatEnumCallbackWtoA(HACMDRIVERID hadid, 00386 PACMFORMATDETAILSW pafdw, 00387 DWORD_PTR dwInstance, 00388 DWORD fdwSupport) 00389 { 00390 struct MSACM_FormatEnumWtoA_Instance* pafei; 00391 00392 pafei = (struct MSACM_FormatEnumWtoA_Instance*)dwInstance; 00393 00394 pafei->pafda->dwFormatIndex = pafdw->dwFormatIndex; 00395 pafei->pafda->dwFormatTag = pafdw->dwFormatTag; 00396 pafei->pafda->fdwSupport = pafdw->fdwSupport; 00397 WideCharToMultiByte( CP_ACP, 0, pafdw->szFormat, -1, 00398 pafei->pafda->szFormat, sizeof(pafei->pafda->szFormat), NULL, NULL ); 00399 00400 return (pafei->fnCallback)(hadid, pafei->pafda, 00401 pafei->dwInstance, fdwSupport); 00402 } 00403 00404 /*********************************************************************** 00405 * acmFormatEnumA (MSACM32.@) 00406 */ 00407 MMRESULT WINAPI acmFormatEnumA(HACMDRIVER had, PACMFORMATDETAILSA pafda, 00408 ACMFORMATENUMCBA fnCallback, 00409 DWORD_PTR dwInstance, DWORD fdwEnum) 00410 { 00411 ACMFORMATDETAILSW afdw; 00412 struct MSACM_FormatEnumWtoA_Instance afei; 00413 00414 if (!pafda) 00415 return MMSYSERR_INVALPARAM; 00416 00417 if (pafda->cbStruct < sizeof(*pafda)) 00418 return MMSYSERR_INVALPARAM; 00419 00420 memset(&afdw, 0, sizeof(afdw)); 00421 afdw.cbStruct = sizeof(afdw); 00422 afdw.dwFormatIndex = pafda->dwFormatIndex; 00423 afdw.dwFormatTag = pafda->dwFormatTag; 00424 afdw.pwfx = pafda->pwfx; 00425 afdw.cbwfx = pafda->cbwfx; 00426 00427 afei.pafda = pafda; 00428 afei.dwInstance = dwInstance; 00429 afei.fnCallback = fnCallback; 00430 00431 return acmFormatEnumW(had, &afdw, MSACM_FormatEnumCallbackWtoA, 00432 (DWORD_PTR)&afei, fdwEnum); 00433 } 00434 00435 /*********************************************************************** 00436 * acmFormatEnumW (MSACM32.@) 00437 */ 00438 static BOOL MSACM_FormatEnumHelper(PWINE_ACMDRIVERID padid, HACMDRIVER had, 00439 PACMFORMATDETAILSW pafd, PWAVEFORMATEX pwfxRef, 00440 ACMFORMATENUMCBW fnCallback, 00441 DWORD_PTR dwInstance, DWORD fdwEnum) 00442 { 00443 ACMFORMATTAGDETAILSW aftd; 00444 unsigned int i, j; 00445 00446 if (fdwEnum & ACM_FORMATENUMF_SUGGEST) { 00447 HDRVR hdrvr; 00448 ACMDRVFORMATSUGGEST adfs; 00449 pafd->dwFormatIndex = 0; 00450 memset(&aftd, 0, sizeof(aftd)); 00451 aftd.cbStruct = sizeof(aftd); 00452 memset(&adfs, 0, sizeof(adfs)); 00453 adfs.cbStruct = sizeof(adfs); 00454 00455 for (i = 0; i < padid->cFormatTags; i++) { 00456 aftd.dwFormatTag = i; 00457 pafd->dwFormatTag = aftd.dwFormatTag; 00458 pafd->pwfx->wFormatTag = pafd->dwFormatTag; 00459 00460 if (acmFormatTagDetailsW(had, &aftd, ACM_FORMATTAGDETAILSF_INDEX) != MMSYSERR_NOERROR) 00461 continue; 00462 00463 adfs.cbwfxSrc = aftd.cbFormatSize; 00464 adfs.cbwfxDst = aftd.cbFormatSize; 00465 adfs.pwfxSrc = pwfxRef; 00466 adfs.pwfxDst = pafd->pwfx; 00467 pafd->fdwSupport = padid->fdwSupport; 00468 00469 if ((fdwEnum & ACM_FORMATENUMF_WFORMATTAG) && 00470 aftd.dwFormatTag != pwfxRef->wFormatTag) 00471 continue; 00472 00473 if ((fdwEnum & ACM_FORMATENUMF_HARDWARE) && 00474 !(pafd->fdwSupport & ACMDRIVERDETAILS_SUPPORTF_HARDWARE)) 00475 continue; 00476 00477 hdrvr = OpenDriver(padid->pszFileName,0,0); 00478 SendDriverMessage(hdrvr,ACMDM_FORMAT_SUGGEST,(LPARAM)&adfs,(fdwEnum & 0x000000FFL)); 00479 00480 if (acmFormatDetailsW(had, pafd, ACM_FORMATDETAILSF_FORMAT) != MMSYSERR_NOERROR) 00481 continue; 00482 00483 pafd->cbwfx = sizeof(*(pafd->pwfx)); 00484 00485 if (!(fnCallback)((HACMDRIVERID)padid, pafd, dwInstance, padid->fdwSupport)) 00486 return FALSE; 00487 } 00488 } else { 00489 for (i = 0; i < padid->cFormatTags; i++) { 00490 memset(&aftd, 0, sizeof(aftd)); 00491 aftd.cbStruct = sizeof(aftd); 00492 aftd.dwFormatTagIndex = i; 00493 if (acmFormatTagDetailsW(had, &aftd, ACM_FORMATTAGDETAILSF_INDEX) != MMSYSERR_NOERROR) 00494 continue; 00495 00496 if ((fdwEnum & ACM_FORMATENUMF_WFORMATTAG) && aftd.dwFormatTag != pwfxRef->wFormatTag) 00497 continue; 00498 00499 for (j = 0; j < aftd.cStandardFormats; j++) { 00500 pafd->dwFormatIndex = j; 00501 pafd->dwFormatTag = aftd.dwFormatTag; 00502 if (acmFormatDetailsW(had, pafd, ACM_FORMATDETAILSF_INDEX) != MMSYSERR_NOERROR) 00503 continue; 00504 00505 if ((fdwEnum & ACM_FORMATENUMF_NCHANNELS) && 00506 pafd->pwfx->nChannels != pwfxRef->nChannels) 00507 continue; 00508 if ((fdwEnum & ACM_FORMATENUMF_NSAMPLESPERSEC) && 00509 pafd->pwfx->nSamplesPerSec != pwfxRef->nSamplesPerSec) 00510 continue; 00511 if ((fdwEnum & ACM_FORMATENUMF_WBITSPERSAMPLE) && 00512 pafd->pwfx->wBitsPerSample != pwfxRef->wBitsPerSample) 00513 continue; 00514 if ((fdwEnum & ACM_FORMATENUMF_HARDWARE) && 00515 !(pafd->fdwSupport & ACMDRIVERDETAILS_SUPPORTF_HARDWARE)) 00516 continue; 00517 00518 /* more checks to be done on fdwEnum */ 00519 00520 if (!(fnCallback)((HACMDRIVERID)padid, pafd, dwInstance, padid->fdwSupport)) 00521 return FALSE; 00522 } 00523 /* the "formats" used by the filters are also reported */ 00524 } 00525 } 00526 return TRUE; 00527 } 00528 00529 /**********************************************************************/ 00530 00531 MMRESULT WINAPI acmFormatEnumW(HACMDRIVER had, PACMFORMATDETAILSW pafd, 00532 ACMFORMATENUMCBW fnCallback, 00533 DWORD_PTR dwInstance, DWORD fdwEnum) 00534 { 00535 PWINE_ACMDRIVERID padid; 00536 WAVEFORMATEX wfxRef; 00537 BOOL ret; 00538 00539 TRACE("(%p, %p, %p, %ld, %d)\n", 00540 had, pafd, fnCallback, dwInstance, fdwEnum); 00541 00542 if (!pafd) 00543 return MMSYSERR_INVALPARAM; 00544 00545 if (pafd->cbStruct < sizeof(*pafd)) 00546 return MMSYSERR_INVALPARAM; 00547 00548 if (fdwEnum & (ACM_FORMATENUMF_WFORMATTAG|ACM_FORMATENUMF_NCHANNELS| 00549 ACM_FORMATENUMF_NSAMPLESPERSEC|ACM_FORMATENUMF_WBITSPERSAMPLE| 00550 ACM_FORMATENUMF_CONVERT|ACM_FORMATENUMF_SUGGEST)) 00551 wfxRef = *pafd->pwfx; 00552 00553 if ((fdwEnum & ACM_FORMATENUMF_HARDWARE) && 00554 !(fdwEnum & (ACM_FORMATENUMF_INPUT|ACM_FORMATENUMF_OUTPUT))) 00555 return MMSYSERR_INVALPARAM; 00556 00557 if ((fdwEnum & ACM_FORMATENUMF_WFORMATTAG) && 00558 (pafd->dwFormatTag != pafd->pwfx->wFormatTag)) 00559 return MMSYSERR_INVALPARAM; 00560 00561 if (fdwEnum & (ACM_FORMATENUMF_CONVERT|ACM_FORMATENUMF_INPUT|ACM_FORMATENUMF_OUTPUT)) 00562 FIXME("Unsupported fdwEnum values %08x\n", fdwEnum); 00563 00564 if (had) { 00565 HACMDRIVERID hadid; 00566 00567 if (acmDriverID((HACMOBJ)had, &hadid, 0) != MMSYSERR_NOERROR) 00568 return MMSYSERR_INVALHANDLE; 00569 MSACM_FormatEnumHelper(MSACM_GetDriverID(hadid), had, pafd, &wfxRef, 00570 fnCallback, dwInstance, fdwEnum); 00571 return MMSYSERR_NOERROR; 00572 } 00573 for (padid = MSACM_pFirstACMDriverID; padid; padid = padid->pNextACMDriverID) { 00574 /* should check for codec only */ 00575 if ((padid->fdwSupport & ACMDRIVERDETAILS_SUPPORTF_DISABLED) || 00576 acmDriverOpen(&had, (HACMDRIVERID)padid, 0) != MMSYSERR_NOERROR) 00577 continue; 00578 ret = MSACM_FormatEnumHelper(padid, had, pafd, &wfxRef, 00579 fnCallback, dwInstance, fdwEnum); 00580 acmDriverClose(had, 0); 00581 if (!ret) break; 00582 } 00583 return MMSYSERR_NOERROR; 00584 } 00585 00586 /*********************************************************************** 00587 * acmFormatSuggest (MSACM32.@) 00588 */ 00589 MMRESULT WINAPI acmFormatSuggest(HACMDRIVER had, PWAVEFORMATEX pwfxSrc, 00590 PWAVEFORMATEX pwfxDst, DWORD cbwfxDst, DWORD fdwSuggest) 00591 { 00592 ACMDRVFORMATSUGGEST adfg; 00593 MMRESULT mmr; 00594 00595 TRACE("(%p, %p, %p, %d, %d)\n", 00596 had, pwfxSrc, pwfxDst, cbwfxDst, fdwSuggest); 00597 00598 if (fdwSuggest & ~(ACM_FORMATSUGGESTF_NCHANNELS|ACM_FORMATSUGGESTF_NSAMPLESPERSEC| 00599 ACM_FORMATSUGGESTF_WBITSPERSAMPLE|ACM_FORMATSUGGESTF_WFORMATTAG)) 00600 return MMSYSERR_INVALFLAG; 00601 00602 adfg.cbStruct = sizeof(adfg); 00603 adfg.fdwSuggest = fdwSuggest; 00604 adfg.pwfxSrc = pwfxSrc; 00605 adfg.cbwfxSrc = (pwfxSrc->wFormatTag == WAVE_FORMAT_PCM) ? 00606 sizeof(WAVEFORMATEX) : (sizeof(WAVEFORMATEX) + pwfxSrc->cbSize); 00607 adfg.pwfxDst = pwfxDst; 00608 adfg.cbwfxDst = cbwfxDst; 00609 00610 if (had == NULL) { 00611 PWINE_ACMDRIVERID padid; 00612 00613 /* MS doc says: ACM finds the best suggestion. 00614 * Well, first found will be the "best" 00615 */ 00616 mmr = ACMERR_NOTPOSSIBLE; 00617 for (padid = MSACM_pFirstACMDriverID; padid; padid = padid->pNextACMDriverID) { 00618 /* should check for codec only */ 00619 if ((padid->fdwSupport & ACMDRIVERDETAILS_SUPPORTF_DISABLED) || 00620 acmDriverOpen(&had, (HACMDRIVERID)padid, 0) != MMSYSERR_NOERROR) 00621 continue; 00622 00623 if (MSACM_Message(had, ACMDM_FORMAT_SUGGEST, (LPARAM)&adfg, 0L) == MMSYSERR_NOERROR) { 00624 mmr = MMSYSERR_NOERROR; 00625 break; 00626 } 00627 acmDriverClose(had, 0); 00628 } 00629 } else { 00630 mmr = MSACM_Message(had, ACMDM_FORMAT_SUGGEST, (LPARAM)&adfg, 0L); 00631 } 00632 return mmr; 00633 } 00634 00635 /*********************************************************************** 00636 * acmFormatTagDetailsA (MSACM32.@) 00637 */ 00638 MMRESULT WINAPI acmFormatTagDetailsA(HACMDRIVER had, PACMFORMATTAGDETAILSA paftda, 00639 DWORD fdwDetails) 00640 { 00641 ACMFORMATTAGDETAILSW aftdw; 00642 MMRESULT mmr; 00643 00644 memset(&aftdw, 0, sizeof(aftdw)); 00645 aftdw.cbStruct = sizeof(aftdw); 00646 aftdw.dwFormatTagIndex = paftda->dwFormatTagIndex; 00647 aftdw.dwFormatTag = paftda->dwFormatTag; 00648 00649 mmr = acmFormatTagDetailsW(had, &aftdw, fdwDetails); 00650 if (mmr == MMSYSERR_NOERROR) { 00651 paftda->dwFormatTag = aftdw.dwFormatTag; 00652 paftda->dwFormatTagIndex = aftdw.dwFormatTagIndex; 00653 paftda->cbFormatSize = aftdw.cbFormatSize; 00654 paftda->fdwSupport = aftdw.fdwSupport; 00655 paftda->cStandardFormats = aftdw.cStandardFormats; 00656 WideCharToMultiByte( CP_ACP, 0, aftdw.szFormatTag, -1, paftda->szFormatTag, 00657 sizeof(paftda->szFormatTag), NULL, NULL ); 00658 } 00659 return mmr; 00660 } 00661 00662 /*********************************************************************** 00663 * acmFormatTagDetailsW (MSACM32.@) 00664 */ 00665 MMRESULT WINAPI acmFormatTagDetailsW(HACMDRIVER had, PACMFORMATTAGDETAILSW paftd, 00666 DWORD fdwDetails) 00667 { 00668 PWINE_ACMDRIVERID padid; 00669 MMRESULT mmr = ACMERR_NOTPOSSIBLE; 00670 00671 TRACE("(%p, %p, %d)\n", had, paftd, fdwDetails); 00672 00673 if (fdwDetails & ~(ACM_FORMATTAGDETAILSF_FORMATTAG|ACM_FORMATTAGDETAILSF_INDEX| 00674 ACM_FORMATTAGDETAILSF_LARGESTSIZE)) 00675 return MMSYSERR_INVALFLAG; 00676 00677 switch (fdwDetails) { 00678 case ACM_FORMATTAGDETAILSF_FORMATTAG: 00679 if (had == NULL) { 00680 for (padid = MSACM_pFirstACMDriverID; padid; padid = padid->pNextACMDriverID) { 00681 /* should check for codec only */ 00682 if (!(padid->fdwSupport & ACMDRIVERDETAILS_SUPPORTF_DISABLED) && 00683 MSACM_FindFormatTagInCache(padid, paftd->dwFormatTag, NULL) && 00684 acmDriverOpen(&had, (HACMDRIVERID)padid, 0) == 0) { 00685 mmr = MSACM_Message(had, ACMDM_FORMATTAG_DETAILS, (LPARAM)paftd, fdwDetails); 00686 acmDriverClose(had, 0); 00687 if (mmr == MMSYSERR_NOERROR) break; 00688 } 00689 } 00690 } else { 00691 PWINE_ACMDRIVER pad = MSACM_GetDriver(had); 00692 00693 if (pad && MSACM_FindFormatTagInCache(pad->obj.pACMDriverID, paftd->dwFormatTag, NULL)) 00694 mmr = MSACM_Message(had, ACMDM_FORMATTAG_DETAILS, (LPARAM)paftd, fdwDetails); 00695 } 00696 break; 00697 00698 case ACM_FORMATTAGDETAILSF_INDEX: 00699 if (had != NULL) { 00700 PWINE_ACMDRIVER pad = MSACM_GetDriver(had); 00701 00702 if (pad && paftd->dwFormatTagIndex < pad->obj.pACMDriverID->cFormatTags) 00703 mmr = MSACM_Message(had, ACMDM_FORMATTAG_DETAILS, (LPARAM)paftd, fdwDetails); 00704 } 00705 break; 00706 00707 case ACM_FORMATTAGDETAILSF_LARGESTSIZE: 00708 if (had == NULL) { 00709 ACMFORMATTAGDETAILSW tmp; 00710 DWORD ft = paftd->dwFormatTag; 00711 00712 for (padid = MSACM_pFirstACMDriverID; padid; padid = padid->pNextACMDriverID) { 00713 /* should check for codec only */ 00714 if (!(padid->fdwSupport & ACMDRIVERDETAILS_SUPPORTF_DISABLED) && 00715 acmDriverOpen(&had, (HACMDRIVERID)padid, 0) == 0) { 00716 00717 memset(&tmp, 0, sizeof(tmp)); 00718 tmp.cbStruct = sizeof(tmp); 00719 tmp.dwFormatTag = ft; 00720 00721 if (MSACM_Message(had, ACMDM_FORMATTAG_DETAILS, 00722 (LPARAM)&tmp, fdwDetails) == MMSYSERR_NOERROR) { 00723 if (mmr == ACMERR_NOTPOSSIBLE || 00724 paftd->cbFormatSize < tmp.cbFormatSize) { 00725 *paftd = tmp; 00726 mmr = MMSYSERR_NOERROR; 00727 } 00728 } 00729 acmDriverClose(had, 0); 00730 } 00731 } 00732 } else { 00733 mmr = MSACM_Message(had, ACMDM_FORMATTAG_DETAILS, (LPARAM)paftd, fdwDetails); 00734 } 00735 break; 00736 00737 default: 00738 WARN("Unsupported fdwDetails=%08x\n", fdwDetails); 00739 mmr = MMSYSERR_ERROR; 00740 } 00741 00742 if (mmr == MMSYSERR_NOERROR && 00743 paftd->dwFormatTag == WAVE_FORMAT_PCM && paftd->szFormatTag[0] == 0) 00744 MultiByteToWideChar( CP_ACP, 0, "PCM", -1, paftd->szFormatTag, 00745 sizeof(paftd->szFormatTag)/sizeof(WCHAR) ); 00746 00747 return mmr; 00748 } 00749 00750 struct MSACM_FormatTagEnumWtoA_Instance { 00751 PACMFORMATTAGDETAILSA paftda; 00752 DWORD_PTR dwInstance; 00753 ACMFORMATTAGENUMCBA fnCallback; 00754 }; 00755 00756 static BOOL CALLBACK MSACM_FormatTagEnumCallbackWtoA(HACMDRIVERID hadid, 00757 PACMFORMATTAGDETAILSW paftdw, 00758 DWORD_PTR dwInstance, 00759 DWORD fdwSupport) 00760 { 00761 struct MSACM_FormatTagEnumWtoA_Instance* paftei; 00762 00763 paftei = (struct MSACM_FormatTagEnumWtoA_Instance*)dwInstance; 00764 00765 paftei->paftda->dwFormatTagIndex = paftdw->dwFormatTagIndex; 00766 paftei->paftda->dwFormatTag = paftdw->dwFormatTag; 00767 paftei->paftda->cbFormatSize = paftdw->cbFormatSize; 00768 paftei->paftda->fdwSupport = paftdw->fdwSupport; 00769 paftei->paftda->cStandardFormats = paftdw->cStandardFormats; 00770 WideCharToMultiByte( CP_ACP, 0, paftdw->szFormatTag, -1, paftei->paftda->szFormatTag, 00771 sizeof(paftei->paftda->szFormatTag), NULL, NULL ); 00772 00773 return (paftei->fnCallback)(hadid, paftei->paftda, 00774 paftei->dwInstance, fdwSupport); 00775 } 00776 00777 /*********************************************************************** 00778 * acmFormatTagEnumA (MSACM32.@) 00779 */ 00780 MMRESULT WINAPI acmFormatTagEnumA(HACMDRIVER had, PACMFORMATTAGDETAILSA paftda, 00781 ACMFORMATTAGENUMCBA fnCallback, 00782 DWORD_PTR dwInstance, DWORD fdwEnum) 00783 { 00784 ACMFORMATTAGDETAILSW aftdw; 00785 struct MSACM_FormatTagEnumWtoA_Instance aftei; 00786 00787 if (!paftda) 00788 return MMSYSERR_INVALPARAM; 00789 00790 if (paftda->cbStruct < sizeof(*paftda)) 00791 return MMSYSERR_INVALPARAM; 00792 00793 if (fdwEnum != 0) 00794 return MMSYSERR_INVALFLAG; 00795 00796 memset(&aftdw, 0, sizeof(aftdw)); 00797 aftdw.cbStruct = sizeof(aftdw); 00798 aftdw.dwFormatTagIndex = paftda->dwFormatTagIndex; 00799 aftdw.dwFormatTag = paftda->dwFormatTag; 00800 00801 aftei.paftda = paftda; 00802 aftei.dwInstance = dwInstance; 00803 aftei.fnCallback = fnCallback; 00804 00805 return acmFormatTagEnumW(had, &aftdw, MSACM_FormatTagEnumCallbackWtoA, 00806 (DWORD_PTR)&aftei, fdwEnum); 00807 } 00808 00809 /*********************************************************************** 00810 * acmFormatTagEnumW (MSACM32.@) 00811 */ 00812 MMRESULT WINAPI acmFormatTagEnumW(HACMDRIVER had, PACMFORMATTAGDETAILSW paftd, 00813 ACMFORMATTAGENUMCBW fnCallback, 00814 DWORD_PTR dwInstance, DWORD fdwEnum) 00815 { 00816 PWINE_ACMDRIVERID padid; 00817 unsigned int i; 00818 BOOL bPcmDone = FALSE; 00819 00820 TRACE("(%p, %p, %p, %ld, %d)\n", 00821 had, paftd, fnCallback, dwInstance, fdwEnum); 00822 00823 if (!paftd) 00824 return MMSYSERR_INVALPARAM; 00825 00826 if (paftd->cbStruct < sizeof(*paftd)) 00827 return MMSYSERR_INVALPARAM; 00828 00829 if (fdwEnum != 0) 00830 return MMSYSERR_INVALFLAG; 00831 00832 /* (WS) MSDN info page says that if had != 0, then we should find 00833 * the specific driver to get its tags from. Therefore I'm removing 00834 * the FIXME call and adding a search block below. It also seems 00835 * that the lack of this functionality was the responsible for 00836 * codecs to be multiply and incorrectly listed. 00837 */ 00838 00839 /* if (had) FIXME("had != NULL, not supported\n"); */ 00840 00841 if (had) { 00842 00843 if (acmDriverID((HACMOBJ)had, (HACMDRIVERID *)&padid, 0) != MMSYSERR_NOERROR) 00844 return MMSYSERR_INVALHANDLE; 00845 00846 for (i = 0; i < padid->cFormatTags; i++) { 00847 paftd->dwFormatTagIndex = i; 00848 if (MSACM_Message(had, ACMDM_FORMATTAG_DETAILS, 00849 (LPARAM)paftd, ACM_FORMATTAGDETAILSF_INDEX) == MMSYSERR_NOERROR) { 00850 if (paftd->dwFormatTag == WAVE_FORMAT_PCM) { 00851 if (paftd->szFormatTag[0] == 0) 00852 MultiByteToWideChar( CP_ACP, 0, "PCM", -1, paftd->szFormatTag, 00853 sizeof(paftd->szFormatTag)/sizeof(WCHAR) ); 00854 /* (WS) I'm preserving this PCM hack since it seems to be 00855 * correct. Please notice this block was borrowed from 00856 * below. 00857 */ 00858 if (bPcmDone) continue; 00859 bPcmDone = TRUE; 00860 } 00861 if (!(fnCallback)((HACMDRIVERID)padid, paftd, dwInstance, padid->fdwSupport)) 00862 return MMSYSERR_NOERROR; 00863 } 00864 } 00865 00866 } 00867 00868 /* if had==0 then search for the first suitable driver */ 00869 else { 00870 for (padid = MSACM_pFirstACMDriverID; padid; padid = padid->pNextACMDriverID) { 00871 /* should check for codec only */ 00872 if (!(padid->fdwSupport & ACMDRIVERDETAILS_SUPPORTF_DISABLED) && 00873 acmDriverOpen(&had, (HACMDRIVERID)padid, 0) == MMSYSERR_NOERROR) { 00874 for (i = 0; i < padid->cFormatTags; i++) { 00875 paftd->dwFormatTagIndex = i; 00876 if (MSACM_Message(had, ACMDM_FORMATTAG_DETAILS, 00877 (LPARAM)paftd, ACM_FORMATTAGDETAILSF_INDEX) == MMSYSERR_NOERROR) { 00878 if (paftd->dwFormatTag == WAVE_FORMAT_PCM) { 00879 if (paftd->szFormatTag[0] == 0) 00880 MultiByteToWideChar( CP_ACP, 0, "PCM", -1, paftd->szFormatTag, 00881 sizeof(paftd->szFormatTag)/sizeof(WCHAR) ); 00882 /* FIXME (EPP): I'm not sure this is the correct 00883 * algorithm (should make more sense to apply the same 00884 * for all already loaded formats, but this will do 00885 * for now 00886 */ 00887 if (bPcmDone) continue; 00888 bPcmDone = TRUE; 00889 } 00890 if (!(fnCallback)((HACMDRIVERID)padid, paftd, dwInstance, padid->fdwSupport)) { 00891 acmDriverClose(had, 0); 00892 return MMSYSERR_NOERROR; 00893 } 00894 } 00895 } 00896 acmDriverClose(had, 0); 00897 } 00898 } 00899 } 00900 return MMSYSERR_NOERROR; 00901 } Generated on Sun May 27 2012 04:17:58 for ReactOS by
1.7.6.1
|