Modified: trunk/reactos/subsys/system/sndvol32/misc.c
Modified: trunk/reactos/subsys/system/sndvol32/mixer.c
Modified: trunk/reactos/subsys/system/sndvol32/sndvol32.c
Modified: trunk/reactos/subsys/system/sndvol32/sndvol32.h
--- trunk/reactos/subsys/system/sndvol32/misc.c 2005-09-27 12:43:36 UTC (rev 18122)
+++ trunk/reactos/subsys/system/sndvol32/misc.c 2005-09-27 13:42:20 UTC (rev 18123)
@@ -127,3 +127,121 @@
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;
+}
--- trunk/reactos/subsys/system/sndvol32/mixer.c 2005-09-27 12:43:36 UTC (rev 18122)
+++ trunk/reactos/subsys/system/sndvol32/mixer.c 2005-09-27 13:42:20 UTC (rev 18123)
@@ -111,6 +111,7 @@
static BOOL
SndMixerQueryControls(PSND_MIXER Mixer,
+ PUINT DisplayControls,
LPMIXERLINE LineInfo,
LPMIXERCONTROL *Controls)
{
@@ -138,7 +139,13 @@
{
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 @@
SndMixerQueryConnections(PSND_MIXER Mixer,
PSND_MIXER_DESTINATION Line)
{
- UINT i;
+ UINT i, DispControls;
MIXERLINE LineInfo;
MMRESULT Result;
BOOL Ret = TRUE;
@@ -188,8 +195,11 @@
PSND_MIXER_CONNECTION Con;
DPRINT("++ Source: %ws\n", LineInfo.szName);
+
+ DispControls = 0;
if (!SndMixerQueryControls(Mixer,
+ &DispControls,
&LineInfo,
&Controls))
{
@@ -205,6 +215,7 @@
{
Con->Info = LineInfo;
Con->Controls = Controls;
+ Con->DisplayControls = DispControls;
Con->Next = Line->Connections;
Line->Connections = Con;
}
@@ -247,15 +258,10 @@
&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 @@
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 @@
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 @@
{
if (!EnumProc(Mixer,
&Line->Info,
+ Line->DisplayControls,
Context))
{
return FALSE;
@@ -463,6 +518,17 @@
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 @@
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;
+}
+
--- trunk/reactos/subsys/system/sndvol32/sndvol32.c 2005-09-27 12:43:36 UTC (rev 18122)
+++ trunk/reactos/subsys/system/sndvol32/sndvol32.c 2005-09-27 13:42:20 UTC (rev 18123)
@@ -51,6 +51,7 @@
DWORD PlaybackID;
DWORD RecordingID;
UINT OtherLines;
+ TCHAR DeviceName[128];
DWORD tmp;
} PREFERENCES_CONTEXT, *PPREFERENCES_CONTEXT;
@@ -98,6 +99,7 @@
static BOOL CALLBACK
PrefDlgAddLine(PSND_MIXER Mixer,
LPMIXERLINE Line,
+ UINT DisplayControls,
PVOID Context)
{
PPREFERENCES_CONTEXT PrefContext = (PPREFERENCES_CONTEXT)Context;
@@ -113,6 +115,8 @@
{
PrefContext->SelectedLine = Line->dwLineID;
}
+
+ DPRINT("!%ws cControls: %d\n", Line->szName, Line->cControls);
}
else
goto AddToOthersLines;
@@ -128,6 +132,7 @@
{
PrefContext->SelectedLine = Line->dwLineID;
}
+ DPRINT("!%ws cControls: %d\n", Line->szName, Line->cControls);
}
else
goto AddToOthersLines;
@@ -196,10 +201,33 @@
(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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
{
LocalFree(lpAppTitle);
}
+
+ CloseAppConfig();
return 0;
}
--- trunk/reactos/subsys/system/sndvol32/sndvol32.h 2005-09-27 12:43:36 UTC (rev 18122)
+++ trunk/reactos/subsys/system/sndvol32/sndvol32.h 2005-09-27 13:42:20 UTC (rev 18123)
@@ -42,6 +42,7 @@
struct _SND_MIXER_CONNECTION *Next;
MIXERLINE Info;
LPMIXERCONTROL Controls;
+ UINT DisplayControls;
} SND_MIXER_CONNECTION, *PSND_MIXER_CONNECTION;
@@ -50,6 +51,7 @@
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 @@
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 @@
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 @@
OUT LPWSTR *lpTarget,
...);
+BOOL
+ReadLineConfig(IN LPTSTR szDeviceName,
+ IN LPTSTR szLineName,
+ IN LPTSTR szControlName,
+ OUT DWORD *Flags);
+
#endif /* __SNDVOL32_H */