From 043d3190957635f3a81a28835998c0b83da6b516 Mon Sep 17 00:00:00 2001 From: Thomas Bluemel Date: Tue, 27 Sep 2005 13:42:20 +0000 Subject: [PATCH] load some settings from the registry svn path=/trunk/; revision=18123 --- reactos/subsys/system/sndvol32/misc.c | 118 ++++++++++++++++++++++ reactos/subsys/system/sndvol32/mixer.c | 103 +++++++++++++++++-- reactos/subsys/system/sndvol32/sndvol32.c | 94 ++++++++++++----- reactos/subsys/system/sndvol32/sndvol32.h | 21 +++- 4 files changed, 298 insertions(+), 38 deletions(-) diff --git a/reactos/subsys/system/sndvol32/misc.c b/reactos/subsys/system/sndvol32/misc.c index 8ab5768ccf0..e7816177b13 100644 --- a/reactos/subsys/system/sndvol32/misc.c +++ b/reactos/subsys/system/sndvol32/misc.c @@ -127,3 +127,121 @@ LoadAndFormatString(IN HINSTANCE hInstance, return Ret; } +/* NOTE: do NOT modify SNDVOL_REG_LINESTATE for binary compatibility with XP! */ +typedef struct _SNDVOL_REG_LINESTATE +{ + DWORD Flags; + WCHAR LineName[MIXER_LONG_NAME_CHARS]; +} SNDVOL_REG_LINESTATE, *PSNDVOL_REG_LINESTATE; + +static const TCHAR AppRegSettings[] = TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Applets\\Volume Control"); +static const TCHAR AppOptionsKey[] = TEXT("Options"); +static const TCHAR LineStatesValue[] = TEXT("LineStates"); +static const TCHAR StyleValue[] = TEXT("Style"); + +HKEY hAppSettingsKey = NULL; + +BOOL +InitAppConfig(VOID) +{ + return RegCreateKeyEx(HKEY_CURRENT_USER, + AppRegSettings, + 0, + NULL, + REG_OPTION_NON_VOLATILE, + KEY_READ | KEY_WRITE, + NULL, + &hAppSettingsKey, + NULL) == ERROR_SUCCESS; +} + +VOID +CloseAppConfig(VOID) +{ + if (hAppSettingsKey != NULL) + { + RegCloseKey(hAppSettingsKey); + hAppSettingsKey = NULL; + } +} + +BOOL +ReadLineConfig(IN LPTSTR szDeviceName, + IN LPTSTR szLineName, + IN LPTSTR szControlName, + OUT DWORD *Flags) +{ + HKEY hLineKey; + DWORD Type; + DWORD i, Size = 0; + PSNDVOL_REG_LINESTATE LineStates = NULL; + TCHAR szDevRegKey[MAX_PATH]; + BOOL Ret = FALSE; + + _stprintf(szDevRegKey, + TEXT("%s\\%s"), + szDeviceName, + szLineName); + + if (RegCreateKeyEx(hAppSettingsKey, + szDevRegKey, + 0, + NULL, + REG_OPTION_NON_VOLATILE, + KEY_READ | KEY_WRITE, + NULL, + &hLineKey, + NULL) == ERROR_SUCCESS) + { + if (RegQueryValueEx(hLineKey, + LineStatesValue, + NULL, + &Type, + NULL, + &Size) != ERROR_SUCCESS || + Type != REG_BINARY || + Size == 0 || (Size % sizeof(SNDVOL_REG_LINESTATE) != 0)) + { + goto ExitClose; + } + + LineStates = HeapAlloc(GetProcessHeap(), + 0, + Size); + + if (LineStates != NULL) + { + if (RegQueryValueEx(hLineKey, + LineStatesValue, + NULL, + &Type, + (LPBYTE)LineStates, + &Size) != ERROR_SUCCESS || + Type != REG_BINARY || + Size == 0 || (Size % sizeof(SNDVOL_REG_LINESTATE) != 0)) + { + goto ExitClose; + } + + /* try to find the control */ + for (i = 0; i < Size / sizeof(SNDVOL_REG_LINESTATE); i++) + { + if (!_tcscmp(szControlName, + LineStates[i].LineName)) + { + *Flags = LineStates[i].Flags; + Ret = TRUE; + break; + } + } + } + +ExitClose: + HeapFree(GetProcessHeap(), + 0, + LineStates); + RegCloseKey(hLineKey); + } + + return Ret; +} diff --git a/reactos/subsys/system/sndvol32/mixer.c b/reactos/subsys/system/sndvol32/mixer.c index a881e96619f..aa171274313 100644 --- a/reactos/subsys/system/sndvol32/mixer.c +++ b/reactos/subsys/system/sndvol32/mixer.c @@ -111,6 +111,7 @@ SndMixerClose(PSND_MIXER Mixer) static BOOL SndMixerQueryControls(PSND_MIXER Mixer, + PUINT DisplayControls, LPMIXERLINE LineInfo, LPMIXERCONTROL *Controls) { @@ -138,7 +139,13 @@ SndMixerQueryControls(PSND_MIXER Mixer, { for (j = 0; j < LineControls.cControls; j++) { - DPRINT("Line control: %ws\n", (*Controls)[j].szName); + if (SndMixerIsDisplayControl(Mixer, + &(*Controls)[j])) + { + (*DisplayControls)++; + } + + DPRINT("Line control: %ws (0x%x, 0x%x)\n", (*Controls)[j].szName, (*Controls)[j].fdwControl, (*Controls)[j].dwControlType); } return TRUE; @@ -169,7 +176,7 @@ static BOOL SndMixerQueryConnections(PSND_MIXER Mixer, PSND_MIXER_DESTINATION Line) { - UINT i; + UINT i, DispControls; MIXERLINE LineInfo; MMRESULT Result; BOOL Ret = TRUE; @@ -188,8 +195,11 @@ SndMixerQueryConnections(PSND_MIXER Mixer, PSND_MIXER_CONNECTION Con; DPRINT("++ Source: %ws\n", LineInfo.szName); + + DispControls = 0; if (!SndMixerQueryControls(Mixer, + &DispControls, &LineInfo, &Controls)) { @@ -205,6 +215,7 @@ SndMixerQueryConnections(PSND_MIXER Mixer, { Con->Info = LineInfo; Con->Controls = Controls; + Con->DisplayControls = DispControls; Con->Next = Line->Connections; Line->Connections = Con; } @@ -247,15 +258,10 @@ SndMixerQueryDestinations(PSND_MIXER Mixer) &Line->Info, MIXER_GETLINEINFOF_DESTINATION) == MMSYSERR_NOERROR) { - DPRINT("+ Destination: %ws (%d)\n", Line->Info.szName, Line->Info.dwComponentType); - - if (!SndMixerQueryConnections(Mixer, Line)) - { - DPRINT("Failed to query mixer connections!\n"); - Ret = FALSE; - break; - } + DPRINT("+ Destination: %ws (0x%x, %d)\n", Line->Info.szName, Line->Info.dwLineID, Line->Info.dwComponentType); + if (!SndMixerQueryControls(Mixer, + &Line->DisplayControls, &Line->Info, &Line->Controls)) { @@ -264,6 +270,13 @@ SndMixerQueryDestinations(PSND_MIXER Mixer) break; } + if (!SndMixerQueryConnections(Mixer, Line)) + { + DPRINT("Failed to query mixer connections!\n"); + Ret = FALSE; + break; + } + Line->Next = Mixer->Lines; Mixer->Lines = Line; } @@ -374,6 +387,47 @@ SndMixerGetProductName(PSND_MIXER Mixer, return -1; } +INT +SndMixerGetLineName(PSND_MIXER Mixer, + DWORD LineID, + LPTSTR lpBuffer, + UINT uSize, + BOOL LongName) +{ + if (Mixer->hmx) + { + int lnsz; + PSND_MIXER_DESTINATION Line; + LPMIXERLINE lpl = NULL; + + for (Line = Mixer->Lines; Line != NULL; Line = Line->Next) + { + if (Line->Info.dwLineID == LineID) + { + lpl = &Line->Info; + break; + } + } + + if (lpl != NULL) + { + lnsz = lstrlen(LongName ? lpl->szName : lpl->szShortName); + if(lnsz + 1 > uSize) + { + return lnsz + 1; + } + else + { + memcpy(lpBuffer, LongName ? lpl->szName : lpl->szShortName, lnsz * sizeof(TCHAR)); + lpBuffer[lnsz] = _T('\0'); + return lnsz; + } + } + } + + return -1; +} + BOOL SndMixerEnumProducts(PSND_MIXER Mixer, PFNSNDMIXENUMPRODUCTS EnumProc, @@ -436,6 +490,7 @@ SndMixerEnumLines(PSND_MIXER Mixer, { if (!EnumProc(Mixer, &Line->Info, + Line->DisplayControls, Context)) { return FALSE; @@ -463,6 +518,17 @@ SndMixerEnumConnections(PSND_MIXER Mixer, if (Line->Info.dwLineID == LineID) { PSND_MIXER_CONNECTION Connection; + + if (Line->DisplayControls != 0) + { + if (!EnumProc(Mixer, + LineID, + &Line->Info, + Context)) + { + return FALSE; + } + } for (Connection = Line->Connections; Connection != NULL; Connection = Connection->Next) { @@ -483,3 +549,20 @@ SndMixerEnumConnections(PSND_MIXER Mixer, return FALSE; } +BOOL +SndMixerIsDisplayControl(PSND_MIXER Mixer, + LPMIXERCONTROL Control) +{ + if (Mixer->hmx && !(Control->fdwControl & MIXERCONTROL_CONTROLF_DISABLED)) + { + switch (Control->dwControlType & MIXERCONTROL_CT_CLASS_MASK) + { + case MIXERCONTROL_CT_CLASS_FADER: + case MIXERCONTROL_CT_CLASS_SWITCH: + return TRUE; + } + } + + return FALSE; +} + diff --git a/reactos/subsys/system/sndvol32/sndvol32.c b/reactos/subsys/system/sndvol32/sndvol32.c index c5c9df1505c..5fc9905c119 100644 --- a/reactos/subsys/system/sndvol32/sndvol32.c +++ b/reactos/subsys/system/sndvol32/sndvol32.c @@ -51,6 +51,7 @@ typedef struct _PREFERENCES_CONTEXT DWORD PlaybackID; DWORD RecordingID; UINT OtherLines; + TCHAR DeviceName[128]; DWORD tmp; } PREFERENCES_CONTEXT, *PPREFERENCES_CONTEXT; @@ -98,6 +99,7 @@ FillDeviceComboBox(PSND_MIXER Mixer, static BOOL CALLBACK PrefDlgAddLine(PSND_MIXER Mixer, LPMIXERLINE Line, + UINT DisplayControls, PVOID Context) { PPREFERENCES_CONTEXT PrefContext = (PPREFERENCES_CONTEXT)Context; @@ -113,6 +115,8 @@ PrefDlgAddLine(PSND_MIXER Mixer, { PrefContext->SelectedLine = Line->dwLineID; } + + DPRINT("!%ws cControls: %d\n", Line->szName, Line->cControls); } else goto AddToOthersLines; @@ -128,6 +132,7 @@ PrefDlgAddLine(PSND_MIXER Mixer, { PrefContext->SelectedLine = Line->dwLineID; } + DPRINT("!%ws cControls: %d\n", Line->szName, Line->cControls); } else goto AddToOthersLines; @@ -196,10 +201,33 @@ PrefDlgAddConnection(PSND_MIXER Mixer, (LPARAM)&lvi); if (i != (UINT)-1) { - /* FIXME - read config from registry */ + TCHAR LineName[MIXER_LONG_NAME_CHARS]; + DWORD Flags; + BOOL SelLine = FALSE; + + if (SndMixerGetLineName(PrefContext->Mixer, + PrefContext->SelectedLine, + LineName, + MIXER_LONG_NAME_CHARS, + FALSE) == -1) + { + LineName[0] = TEXT('\0'); + } + + if (ReadLineConfig(PrefContext->DeviceName, + LineName, + Line->szName, + &Flags)) + { + if (Flags != 0x4) + { + SelLine = TRUE; + } + } + ListView_SetCheckState(hwndControls, i, - FALSE); + SelLine); } } @@ -214,18 +242,18 @@ UpdatePrefDlgControls(PPREFERENCES_CONTEXT Context, INT DeviceCbIndex; /* select the mixer */ - DeviceCbIndex = SendMessage(GetDlgItem(Context->hwndDlg, - IDC_MIXERDEVICE), - CB_GETCURSEL, - 0, - 0); + DeviceCbIndex = SendDlgItemMessage(Context->hwndDlg, + IDC_MIXERDEVICE, + CB_GETCURSEL, + 0, + 0); if (DeviceCbIndex != CB_ERR) { - MixerID = SendMessage(GetDlgItem(Context->hwndDlg, - IDC_MIXERDEVICE), - CB_GETITEMDATA, - DeviceCbIndex, - 0); + MixerID = SendDlgItemMessage(Context->hwndDlg, + IDC_MIXERDEVICE, + CB_GETITEMDATA, + DeviceCbIndex, + 0); if (MixerID == CB_ERR) { MixerID = 0; @@ -244,6 +272,10 @@ UpdatePrefDlgControls(PPREFERENCES_CONTEXT Context, Context->RecordingID = (DWORD)-1; Context->OtherLines = 0; Context->SelectedLine = (DWORD)-1; + + SndMixerGetProductName(Context->Mixer, + Context->DeviceName, + sizeof(Context->DeviceName) / sizeof(Context->DeviceName[0])); if (SndMixerEnumLines(Context->Mixer, PrefDlgAddLine, @@ -271,11 +303,11 @@ UpdatePrefDlgControls(PPREFERENCES_CONTEXT Context, if (Context->OtherLines != 0) { /* select the first item in the other lines combo box by default */ - SendMessage(GetDlgItem(Context->hwndDlg, - IDC_LINE), - CB_SETCURSEL, - 0, - 0); + SendDlgItemMessage(Context->hwndDlg, + IDC_LINE, + CB_SETCURSEL, + 0, + 0); } EnableWindow(GetDlgItem(Context->hwndDlg, IDC_LINE), @@ -349,18 +381,18 @@ DlgPreferencesProc(HWND hwndDlg, DWORD LineID; DWORD Index; - Index = SendMessage(GetDlgItem(hwndDlg, - IDC_LINE), - CB_GETCURSEL, - 0, - 0); + Index = SendDlgItemMessage(hwndDlg, + IDC_LINE, + CB_GETCURSEL, + 0, + 0); if (Index != CB_ERR) { - LineID = SendMessage(GetDlgItem(hwndDlg, - IDC_LINE), - CB_GETITEMDATA, - Index, - 0); + LineID = SendDlgItemMessage(hwndDlg, + IDC_LINE, + CB_GETITEMDATA, + Index, + 0); if (LineID != CB_ERR) { UpdatePrefDlgControls(Context, @@ -769,6 +801,12 @@ WinMain(HINSTANCE hInstance, hAppInstance = hInstance; hAppHeap = GetProcessHeap(); + if (!InitAppConfig()) + { + DPRINT("Unable to open the Volume Control registry key!\n"); + return 1; + } + /* load the application title */ if (AllocAndLoadString(&lpAppTitle, hAppInstance, @@ -809,6 +847,8 @@ WinMain(HINSTANCE hInstance, { LocalFree(lpAppTitle); } + + CloseAppConfig(); return 0; } diff --git a/reactos/subsys/system/sndvol32/sndvol32.h b/reactos/subsys/system/sndvol32/sndvol32.h index 23c28777e40..f4d33dc5971 100644 --- a/reactos/subsys/system/sndvol32/sndvol32.h +++ b/reactos/subsys/system/sndvol32/sndvol32.h @@ -42,6 +42,7 @@ typedef struct _SND_MIXER_CONNECTION struct _SND_MIXER_CONNECTION *Next; MIXERLINE Info; LPMIXERCONTROL Controls; + UINT DisplayControls; } SND_MIXER_CONNECTION, *PSND_MIXER_CONNECTION; @@ -50,6 +51,7 @@ typedef struct _SND_MIXER_DESTINATION struct _SND_MIXER_DESTINATION *Next; MIXERLINE Info; LPMIXERCONTROL Controls; + UINT DisplayControls; PSND_MIXER_CONNECTION Connections; } SND_MIXER_DESTINATION, *PSND_MIXER_DESTINATION; @@ -63,7 +65,7 @@ typedef struct _SND_MIXER PSND_MIXER_DESTINATION Lines; } SND_MIXER, *PSND_MIXER; -typedef BOOL (CALLBACK *PFNSNDMIXENUMLINES)(PSND_MIXER Mixer, LPMIXERLINE Line, PVOID Context); +typedef BOOL (CALLBACK *PFNSNDMIXENUMLINES)(PSND_MIXER Mixer, LPMIXERLINE Line, UINT DisplayControls, PVOID Context); typedef BOOL (CALLBACK *PFNSNDMIXENUMCONNECTIONS)(PSND_MIXER Mixer, DWORD LineID, LPMIXERLINE Line, PVOID Context); typedef BOOL (CALLBACK *PFNSNDMIXENUMPRODUCTS)(PSND_MIXER Mixer, UINT Id, LPCTSTR ProductName, PVOID Context); @@ -73,14 +75,25 @@ VOID SndMixerClose(PSND_MIXER Mixer); BOOL SndMixerSelect(PSND_MIXER Mixer, UINT MixerId); UINT SndMixerGetSelection(PSND_MIXER Mixer); INT SndMixerGetProductName(PSND_MIXER Mixer, LPTSTR lpBuffer, UINT uSize); +INT SndMixerGetLineName(PSND_MIXER Mixer, DWORD LineID, LPTSTR lpBuffer, UINT uSize, BOOL LongName); BOOL SndMixerEnumProducts(PSND_MIXER Mixer, PFNSNDMIXENUMPRODUCTS EnumProc, PVOID Context); INT SndMixerGetDestinationCount(PSND_MIXER Mixer); BOOL SndMixerEnumLines(PSND_MIXER Mixer, PFNSNDMIXENUMLINES EnumProc, PVOID Context); BOOL SndMixerEnumConnections(PSND_MIXER Mixer, DWORD LineID, PFNSNDMIXENUMCONNECTIONS EnumProc, PVOID Context); +BOOL SndMixerIsDisplayControl(PSND_MIXER Mixer, LPMIXERCONTROL Control); /* * MISC */ + +extern HKEY hAppSettingsKey; + +BOOL +InitAppConfig(VOID); + +VOID +CloseAppConfig(VOID); + INT AllocAndLoadString(OUT LPWSTR *lpTarget, IN HINSTANCE hInst, @@ -92,4 +105,10 @@ LoadAndFormatString(IN HINSTANCE hInstance, OUT LPWSTR *lpTarget, ...); +BOOL +ReadLineConfig(IN LPTSTR szDeviceName, + IN LPTSTR szLineName, + IN LPTSTR szControlName, + OUT DWORD *Flags); + #endif /* __SNDVOL32_H */