From: David Quintana Date: Mon, 28 Jul 2014 13:24:56 +0000 (+0000) Subject: [STOBJECT] X-Git-Tag: backups/shell-experiments@75904~192 X-Git-Url: https://git.reactos.org/?p=reactos.git;a=commitdiff_plain;h=149d0f17d340fe5e5a62185aa610901dbf7ee74c [STOBJECT] * Nothing happened. No files were missing. Look elsewhere. svn path=/branches/shell-experiments/; revision=63752 --- diff --git a/dll/win32/stobject/volume.cpp b/dll/win32/stobject/volume.cpp new file mode 100644 index 00000000000..133809a48a6 --- /dev/null +++ b/dll/win32/stobject/volume.cpp @@ -0,0 +1,230 @@ +/* + * PROJECT: ReactOS system libraries + * LICENSE: GPL - See COPYING in the top level directory + * FILE: dll\win32\stobject\volume.cpp + * PURPOSE: Systray shell service object + * PROGRAMMERS: Robert Naumann + David Quintana + */ + +#include "precomp.h" + +#include +#include + +HICON g_hIconVolume; +HICON g_hIconMute; + +HMIXER g_hMixer; +UINT g_mixerId; +DWORD g_mixerLineID; +DWORD g_muteControlID; + +UINT g_mmDeviceChange; + +BOOL g_IsMute = FALSE; + +static HRESULT __stdcall Volume_FindMixerControl(CSysTray * pSysTray) +{ + MMRESULT result; + UINT mixerId = 0; + DWORD waveOutId = 0; + DWORD param2 = 0; + + DbgPrint("Volume_FindDefaultMixerID\n"); + + result = waveOutMessage((HWAVEOUT) WAVE_MAPPER, DRVM_MAPPER_PREFERRED_GET, (DWORD) &waveOutId, (DWORD) ¶m2); + if (result) + return E_FAIL; + + if (waveOutId == (DWORD)-1) + { + DbgPrint("WARNING: waveOut has no default device, trying with first available device...\n", waveOutId); + + mixerId = 0; + } + else + { + DbgPrint("waveOut default device is %d\n", waveOutId); + + result = mixerGetID((HMIXEROBJ) waveOutId, &mixerId, MIXER_OBJECTF_WAVEOUT); + if (result) + return E_FAIL; + + DbgPrint("mixerId for waveOut default device is %d\n", mixerId); + } + + g_mixerId = mixerId; + return S_OK; + + MIXERCAPS mixerCaps; + MIXERLINE mixerLine; + MIXERCONTROL mixerControl; + MIXERLINECONTROLS mixerLineControls; + + g_mixerLineID = -1; + g_muteControlID = -1; + + if (mixerGetDevCapsW(g_mixerId, &mixerCaps, sizeof(mixerCaps))) + return E_FAIL; + + if (mixerCaps.cDestinations == 0) + return S_FALSE; + + DbgPrint("mixerCaps.cDestinations %d\n", mixerCaps.cDestinations); + + DWORD idx; + for (idx = 0; idx < mixerCaps.cDestinations; idx++) + { + mixerLine.cbStruct = sizeof(mixerLine); + mixerLine.dwDestination = idx; + if (!mixerGetLineInfoW((HMIXEROBJ) g_mixerId, &mixerLine, 0)) + { + if (mixerLine.dwComponentType >= MIXERLINE_COMPONENTTYPE_DST_SPEAKERS && + mixerLine.dwComponentType <= MIXERLINE_COMPONENTTYPE_DST_HEADPHONES) + break; + DbgPrint("Destination %d was not speakers or headphones.\n"); + } + } + + if (idx >= mixerCaps.cDestinations) + return E_FAIL; + + DbgPrint("Valid destination %d found.\n"); + + g_mixerLineID = mixerLine.dwLineID; + + mixerLineControls.cbStruct = sizeof(mixerLineControls); + mixerLineControls.dwLineID = mixerLine.dwLineID; + mixerLineControls.cControls = 1; + mixerLineControls.dwControlType = MIXERCONTROL_CONTROLTYPE_MUTE; + mixerLineControls.pamxctrl = &mixerControl; + mixerLineControls.cbmxctrl = sizeof(mixerControl); + + if (mixerGetLineControlsW((HMIXEROBJ) g_mixerId, &mixerLineControls, MIXER_GETLINECONTROLSF_ONEBYTYPE)) + return E_FAIL; + + DbgPrint("Found control id %d for mute: %d\n", mixerControl.dwControlID); + + g_muteControlID = mixerControl.dwControlID; + + return S_OK; +} + +HRESULT Volume_IsMute() +{ + MIXERCONTROLDETAILS mixerControlDetails; + + if (g_mixerId != (UINT)-1 && g_muteControlID != (DWORD)-1) + { + BOOL detailsResult = 0; + mixerControlDetails.cbStruct = sizeof(mixerControlDetails); + mixerControlDetails.hwndOwner = 0; + mixerControlDetails.dwControlID = g_muteControlID; + mixerControlDetails.cChannels = 1; + mixerControlDetails.paDetails = &detailsResult; + mixerControlDetails.cbDetails = sizeof(detailsResult); + if (mixerGetControlDetailsW((HMIXEROBJ) g_mixerId, &mixerControlDetails, 0)) + return E_FAIL; + + DbgPrint("Obtained mute status %d\n", detailsResult); + + g_IsMute = detailsResult != 0; + } + + return S_OK; +} + +HRESULT STDMETHODCALLTYPE Volume_Init(_In_ CSysTray * pSysTray) +{ + HRESULT hr; + + DbgPrint("Volume_Init\n"); + + if (!g_hMixer) + { + hr = Volume_FindMixerControl(pSysTray); + if (FAILED(hr)) + return hr; + + g_mmDeviceChange = RegisterWindowMessageW(L"winmm_devicechange"); + } + + g_hIconVolume = LoadIcon(g_hInstance, MAKEINTRESOURCE(IDI_VOLUME)); + g_hIconMute = LoadIcon(g_hInstance, MAKEINTRESOURCE(IDI_VOLMUTE)); + + Volume_IsMute(); + + HICON icon; + if (g_IsMute) + icon = g_hIconMute; + else + icon = g_hIconVolume; + + pSysTray->NotifyIcon(NIM_ADD, ID_ICON_VOLUME, icon, L"Placeholder"); + return pSysTray->NotifyIcon(NIM_MODIFY, ID_ICON_VOLUME, icon, L"Placeholder"); +} + +HRESULT STDMETHODCALLTYPE Volume_Update(_In_ CSysTray * pSysTray) +{ + DbgPrint("Volume_Update\n"); + + Volume_IsMute(); + + HICON icon; + if (g_IsMute) + icon = g_hIconMute; + else + icon = g_hIconVolume; + + return pSysTray->NotifyIcon(NIM_MODIFY, ID_ICON_VOLUME, icon, L"Placeholder"); +} + +HRESULT STDMETHODCALLTYPE Volume_Shutdown(_In_ CSysTray * pSysTray) +{ + DbgPrint("Volume_Shutdown\n"); + + return pSysTray->NotifyIcon(NIM_DELETE, ID_ICON_VOLUME, NULL, NULL); +} + +HRESULT Volume_OnDeviceChange(_In_ CSysTray * pSysTray, WPARAM wParam, LPARAM lParam) +{ + return Volume_FindMixerControl(pSysTray); +} + +HRESULT STDMETHODCALLTYPE Volume_Message(_In_ CSysTray * pSysTray, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + if (uMsg == g_mmDeviceChange) + return Volume_OnDeviceChange(pSysTray, wParam, lParam); + + if (uMsg != ID_ICON_VOLUME) + return S_FALSE; + + DbgPrint("Volume_Message\n"); + + DbgPrint("Calling update...\n"); + Volume_Update(pSysTray); + + switch (lParam) + { + case WM_LBUTTONDOWN: + break; + case WM_LBUTTONUP: + DbgPrint("TODO: display volume slider\n"); + break; + case WM_LBUTTONDBLCLK: + // FIXME: ensure we are loading the right one + ShellExecute(NULL, NULL, L"sndvol32.exe", NULL, NULL, SW_SHOWNORMAL); + break; + case WM_RBUTTONDOWN: + break; + case WM_RBUTTONUP: + break; + case WM_RBUTTONDBLCLK: + break; + case WM_MOUSEMOVE: + break; + } + + return S_OK; +}