//--------------------------------------------------------------------------; // // File: speakers.cpp // // Copyright (c) 1997 Microsoft Corporation. All rights reserved // //--------------------------------------------------------------------------; #include "mmcpl.h" #include #ifdef DEBUG #undef DEBUG #include #define DEBUG #else #include #endif #include #include #include #include "utils.h" #include "medhelp.h" #include #include "advaudio.h" #include "speakers.h" #include "dslevel.h" ///////////// // defines ///////////// #define NUMCONFIG (MAX_SPEAKER_TYPE + 1) ////////// // Globals ////////// DWORD gdwSpeakerTable[NUMCONFIG] = { DSSPEAKER_DIRECTOUT, DSSPEAKER_HEADPHONE, SPEAKERS_DEFAULT_CONFIG, DSSPEAKER_MONO, DSSPEAKER_COMBINED(DSSPEAKER_STEREO, DSSPEAKER_GEOMETRY_NARROW), DSSPEAKER_COMBINED(DSSPEAKER_STEREO, DSSPEAKER_GEOMETRY_NARROW), DSSPEAKER_COMBINED(DSSPEAKER_STEREO, DSSPEAKER_GEOMETRY_NARROW), DSSPEAKER_COMBINED(DSSPEAKER_STEREO, DSSPEAKER_GEOMETRY_WIDE), DSSPEAKER_COMBINED(DSSPEAKER_STEREO, DSSPEAKER_GEOMETRY_NARROW), DSSPEAKER_QUAD, DSSPEAKER_SURROUND, DSSPEAKER_5POINT1, DSSPEAKER_7POINT1 }; DWORD gdwImageID[NUMCONFIG] = { IDB_NOSPEAKERS, IDB_HEADPHONES, IDB_STEREODESKTOP, IDB_MONOLAPTOP, IDB_STEREOLAPTOP, IDB_STEREOMONITOR, IDB_STEREOCPU, IDB_MOUNTEDSTEREO, IDB_STEREOKEYBOARD, IDB_QUADRAPHONIC, IDB_SURROUND, IDB_SURROUND_5_1, IDB_SURROUND_7_1 }; HBITMAP ghBitmaps[NUMCONFIG]; ////////////// // Help ID's ////////////// #pragma data_seg(".text") const static DWORD aAdvSpeakerHelp[] = { IDC_SPEAKERCONFIG, IDH_SPEAKERS_PICKER, IDC_IMAGEFRAME, IDH_SPEAKERS_IMAGE, IDC_ICON_4, IDH_COMM_GROUPBOX, IDC_TEXT_22, IDH_COMM_GROUPBOX, IDC_TEXT_23, IDH_SPEAKERS_PICKER, 0, 0 }; #pragma data_seg() ////////////// // Functions ////////////// // // Verifies that the speakers type and config match, if not, change type to match config using default type // void VerifySpeakerConfig(DWORD dwSpeakerConfig, LPDWORD pdwSpeakerType) { if (pdwSpeakerType) { DWORD dwType = *pdwSpeakerType; if (gdwSpeakerTable[dwType] != dwSpeakerConfig) // the type doesn't match the config, pick a default type { switch (dwSpeakerConfig) { case DSSPEAKER_DIRECTOUT: *pdwSpeakerType = TYPE_NOSPEAKERS; break; case DSSPEAKER_HEADPHONE: *pdwSpeakerType = TYPE_HEADPHONES; break; case DSSPEAKER_MONO: *pdwSpeakerType = TYPE_MONOLAPTOP; break; case DSSPEAKER_STEREO: *pdwSpeakerType = TYPE_STEREODESKTOP; break; case DSSPEAKER_QUAD: *pdwSpeakerType = TYPE_QUADRAPHONIC; break; case DSSPEAKER_SURROUND: *pdwSpeakerType = TYPE_SURROUND; break; case DSSPEAKER_5POINT1: *pdwSpeakerType = TYPE_SURROUND_5_1; break; case DSSPEAKER_7POINT1: *pdwSpeakerType = TYPE_SURROUND_7_1; break; default: { if (DSSPEAKER_CONFIG(dwSpeakerConfig) == DSSPEAKER_STEREO) { DWORD dwAngle = DSSPEAKER_GEOMETRY(dwSpeakerConfig); DWORD dwMiddle = DSSPEAKER_GEOMETRY_NARROW + ((DSSPEAKER_GEOMETRY_WIDE - DSSPEAKER_GEOMETRY_NARROW) >> 1); if (dwAngle <= dwMiddle) { *pdwSpeakerType = TYPE_STEREOCPU; } else { *pdwSpeakerType = TYPE_STEREODESKTOP; } } } break; } } } } // // Given a speaker type, returns the DirectSound config for it // DWORD GetSpeakerConfigFromType(DWORD dwType) { DWORD dwConfig = SPEAKERS_DEFAULT_CONFIG; if (dwType < (DWORD)NUMCONFIG) { dwConfig = gdwSpeakerTable[dwType]; } return(dwConfig); } // // Called when first started up, it determines the current state of the device's speaker state // and fills out the controls as appropriate // BOOL InitSpeakerDlg(HWND hwnd, BOOL fImagesOnly) { TCHAR str[255]; int item; DWORD dwIndex; HWND hwndCombo; if (!fImagesOnly) { SendDlgItemMessage(hwnd, IDC_SPEAKERCONFIG, CB_RESETCONTENT,0,0); } for (item = 0; item < NUMCONFIG; item++) { if (!fImagesOnly) { LoadString( ghInst, IDS_SPEAKER1 + item, str, sizeof( str )/sizeof(TCHAR) ); SendDlgItemMessage(hwnd, IDC_SPEAKERCONFIG, CB_INSERTSTRING, (WPARAM) -1, (LPARAM) str); } if (ghBitmaps[item] != NULL) { DeleteObject( (HGDIOBJ) ghBitmaps[item]); ghBitmaps[item] = NULL; } ghBitmaps[item] = (HBITMAP) LoadImage(ghInst,MAKEINTATOM(gdwImageID[item]), IMAGE_BITMAP, 0, 0, LR_LOADMAP3DCOLORS); } dwIndex = gAudData.current.dwSpeakerType; SendDlgItemMessage(hwnd, IDC_SPEAKERCONFIG, CB_SETCURSEL, (WPARAM) dwIndex, 0); SendDlgItemMessage(hwnd, IDC_IMAGEFRAME, STM_SETIMAGE, IMAGE_BITMAP, (LPARAM) ghBitmaps[dwIndex]); // Enable/disable the combo box appropriately hwndCombo = GetDlgItem( hwnd, IDC_SPEAKERCONFIG ); if (hwndCombo) { // Check if we can set the speaker configuration if (FAILED(CheckDSSpeakerConfigPriv(gAudData.devGuid, gAudData.fRecord, NULL))) { // No - disable the combo box EnableWindow( hwndCombo, FALSE ); } else { // Yes - enable the combo box EnableWindow( hwndCombo, TRUE ); } } return(TRUE); } // // called to delete all loaded bitmaps // void DumpBitmaps(void) { int item; for (item = 0; item < NUMCONFIG; item++) { if (ghBitmaps[item] != NULL) { DeleteObject( (HGDIOBJ) ghBitmaps[item]); ghBitmaps[item] = NULL; } } } // // called by dialog handler when speaker type is changed // void ChangeSpeakers(HWND hwnd) { DWORD dwIndex; dwIndex = (DWORD)SendDlgItemMessage(hwnd, IDC_SPEAKERCONFIG, CB_GETCURSEL,0,0); if (dwIndex != CB_ERR) { gAudData.current.dwSpeakerType = dwIndex; gAudData.current.dwSpeakerConfig = GetSpeakerConfigFromType(gAudData.current.dwSpeakerType); SendDlgItemMessage(hwnd, IDC_IMAGEFRAME, STM_SETIMAGE, IMAGE_BITMAP, (LPARAM) ghBitmaps[dwIndex]); ToggleApplyButton(hwnd); } } // // Dialog event handler // INT_PTR CALLBACK SpeakerHandler(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) { BOOL fReturnVal = TRUE; switch (msg) { default: fReturnVal = FALSE; break; case WM_INITDIALOG: { fReturnVal = InitSpeakerDlg(hDlg, FALSE); } break; case WM_DESTROY: { DumpBitmaps(); } break; case WM_CONTEXTMENU: { WinHelp((HWND)wParam, gszHelpFile, HELP_CONTEXTMENU, (UINT_PTR)(LPTSTR)aAdvSpeakerHelp); fReturnVal = TRUE; } break; case WM_HELP: { WinHelp((HWND) ((LPHELPINFO)lParam)->hItemHandle, gszHelpFile, HELP_WM_HELP, (UINT_PTR)(LPTSTR)aAdvSpeakerHelp); fReturnVal = TRUE; } break; case WM_SYSCOLORCHANGE: { fReturnVal = InitSpeakerDlg(hDlg, TRUE); } break; case WM_COMMAND: { switch (LOWORD(wParam)) { case IDC_SPEAKERCONFIG: { if (HIWORD(wParam) == CBN_SELCHANGE) { ChangeSpeakers(hDlg); } } break; default: fReturnVal = FALSE; break; } break; } case WM_NOTIFY: { LPNMHDR pnmh = (LPNMHDR) lParam; switch (pnmh->code) { case PSN_APPLY: { ApplyCurrentSettings(&gAudData); } } } } return fReturnVal; }