ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

format.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.