wip: default callback
This commit is contained in:
parent
24110624fb
commit
1a4692533d
7 changed files with 230 additions and 15 deletions
BIN
assets/SoundVolumeView.exe
Normal file
BIN
assets/SoundVolumeView.exe
Normal file
Binary file not shown.
|
|
@ -1,2 +1,4 @@
|
|||
qmake -o build\Makefile .\qtest.pro
|
||||
copy /Y /B .\assets\SoundVolumeView.exe .\build\debug
|
||||
copy /Y /B .\assets\SoundVolumeView.exe .\build\release
|
||||
mingw32-make.exe -C .\build -f Makefile
|
||||
|
|
|
|||
|
|
@ -66,6 +66,124 @@ HRESULT EndpointVolumeCallback::OnNotify(PAUDIO_VOLUME_NOTIFICATION_DATA pNotify
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* EndpointSituationCallback::EndpointSituationCallback(IMMDeviceEnumerator *deviceEnumerator, std::vector<Endpoint*> playbackDevices){
|
||||
* this->deviceEnumerator = deviceEnumerator;
|
||||
* this->playbackDevices = playbackDevices;
|
||||
* }
|
||||
*/
|
||||
|
||||
void EndpointSituationCallback::fill(IMMDeviceEnumerator *deviceEnumerator, std::vector<Endpoint*> playbackDevices){
|
||||
this->deviceEnumerator = deviceEnumerator;
|
||||
this->playbackDevices = playbackDevices;
|
||||
}
|
||||
|
||||
|
||||
ULONG EndpointSituationCallback::AddRef(){
|
||||
return InterlockedIncrement(&ref);
|
||||
}
|
||||
|
||||
ULONG EndpointSituationCallback::Release(){
|
||||
ULONG tempRef = InterlockedDecrement(&ref);
|
||||
if (tempRef == 0) {
|
||||
delete this;
|
||||
}
|
||||
return tempRef;
|
||||
}
|
||||
|
||||
HRESULT EndpointSituationCallback::QueryInterface(REFIID riid, VOID **ppvInterface) {
|
||||
if (IID_IUnknown == riid)
|
||||
{
|
||||
AddRef();
|
||||
*ppvInterface = (IUnknown*)this;
|
||||
}
|
||||
else if (__uuidof(IMMNotificationClient) == riid)
|
||||
{
|
||||
AddRef();
|
||||
*ppvInterface = (IMMNotificationClient*)this;
|
||||
}
|
||||
else
|
||||
{
|
||||
*ppvInterface = NULL;
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT EndpointSituationCallback::OnDefaultDeviceChanged(EDataFlow flow, ERole role,LPCWSTR pwstrDeviceId) {
|
||||
if (flow == EDataFlow::eCapture) return E_INVALIDARG;
|
||||
|
||||
Roles nRole;
|
||||
switch (role) {
|
||||
case ERole::eConsole:
|
||||
nRole = Roles::ROLE_CONSOLE;
|
||||
break;
|
||||
case ERole::eMultimedia:
|
||||
nRole = Roles::ROLE_MULTIMEDIA;
|
||||
break;
|
||||
case ERole::eCommunications:
|
||||
nRole = Roles::ROLE_COMMUNICATIONS;
|
||||
break;
|
||||
}
|
||||
|
||||
osh
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT EndpointSituationCallback::OnDeviceAdded(LPCWSTR pwstrDeviceId) {
|
||||
|
||||
printf(" -->Added device\n");
|
||||
return S_OK;
|
||||
};
|
||||
|
||||
HRESULT EndpointSituationCallback::OnDeviceRemoved(LPCWSTR pwstrDeviceId) {
|
||||
|
||||
printf(" -->Removed device\n");
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT EndpointSituationCallback::OnDeviceStateChanged(LPCWSTR pwstrDeviceId, DWORD dwNewState) {
|
||||
/*
|
||||
* char *pszState = "?????";
|
||||
*
|
||||
* switch (dwNewState)
|
||||
* {
|
||||
* case DEVICE_STATE_ACTIVE:
|
||||
* pszState = "ACTIVE";
|
||||
* break;
|
||||
* case DEVICE_STATE_DISABLED:
|
||||
* pszState = "DISABLED";
|
||||
* break;
|
||||
* case DEVICE_STATE_NOTPRESENT:
|
||||
* pszState = "NOTPRESENT";
|
||||
* break;
|
||||
* case DEVICE_STATE_UNPLUGGED:
|
||||
* pszState = "UNPLUGGED";
|
||||
* break;
|
||||
* }
|
||||
*
|
||||
* printf(" -->New device state is DEVICE_STATE_%s (0x%8.8x)\n",
|
||||
* pszState, dwNewState);
|
||||
*/
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT EndpointSituationCallback::OnPropertyValueChanged(LPCWSTR pwstrDeviceId, const PROPERTYKEY key) {
|
||||
/*
|
||||
* printf(" -->Changed device property "
|
||||
* "{%8.8x-%4.4x-%4.4x-%2.2x%2.2x-%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x}#%d\n",
|
||||
* key.fmtid.Data1, key.fmtid.Data2, key.fmtid.Data3,
|
||||
* key.fmtid.Data4[0], key.fmtid.Data4[1],
|
||||
* key.fmtid.Data4[2], key.fmtid.Data4[3],
|
||||
* key.fmtid.Data4[4], key.fmtid.Data4[5],
|
||||
* key.fmtid.Data4[6], key.fmtid.Data4[7],
|
||||
* key.pid);
|
||||
*/
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
Endpoint::Endpoint(IMMDevice* ep, uint64_t idx){
|
||||
this->endpoint = ep;
|
||||
this->idx = idx;
|
||||
|
|
@ -168,7 +286,51 @@ uint8_t Endpoint::getRoles(){
|
|||
return this->endpointRoles;
|
||||
}
|
||||
|
||||
void Endpoint::setRoles(uint8_t role){
|
||||
void Endpoint::setRoles(Roles role){
|
||||
//otro exe momento
|
||||
STARTUPINFOEXW startupConfig;
|
||||
PROCESS_INFORMATION processInfo;
|
||||
SecureZeroMemory(&startupConfig, sizeof(STARTUPINFOEXW));
|
||||
SecureZeroMemory(&startupConfig.StartupInfo, sizeof(STARTUPINFOW));
|
||||
startupConfig.StartupInfo.cb = sizeof(STARTUPINFOEXW);
|
||||
SecureZeroMemory(&processInfo, sizeof(PROCESS_INFORMATION));
|
||||
|
||||
//const wchar_t* pCrutch = crutch.c_str();
|
||||
std::wstring command = L"SoundVolumeView.exe /SetDefault " + endpointId + L" ";
|
||||
switch (role) {
|
||||
case Roles::ROLE_ALL:
|
||||
command += L"all";
|
||||
break;
|
||||
case Roles::ROLE_CONSOLE:
|
||||
command += std::to_wstring(0);
|
||||
break;
|
||||
case Roles::ROLE_MULTIMEDIA:
|
||||
command += std::to_wstring(1);
|
||||
break;
|
||||
case Roles::ROLE_COMMUNICATIONS:
|
||||
command += std::to_wstring(2);
|
||||
break;
|
||||
}
|
||||
|
||||
if(CreateProcessW(
|
||||
NULL,
|
||||
(wchar_t*)command.c_str(),
|
||||
NULL,
|
||||
NULL,
|
||||
false,
|
||||
CREATE_UNICODE_ENVIRONMENT,
|
||||
NULL,
|
||||
NULL,
|
||||
(LPSTARTUPINFOW)&startupConfig,
|
||||
&processInfo
|
||||
) == true) {
|
||||
WaitForSingleObject(processInfo.hProcess, INFINITE );
|
||||
CloseHandle(processInfo.hProcess);
|
||||
CloseHandle(processInfo.hThread);
|
||||
}
|
||||
}
|
||||
|
||||
void Endpoint::assignRoles(uint8_t role){
|
||||
//todo: operador virtuoso
|
||||
uint8_t roles = endpointRoles | role;
|
||||
this->endpointRoles = roles;
|
||||
|
|
@ -252,30 +414,24 @@ void Overseer::reloadEndpoints() {
|
|||
int comparison = CompareStringEx(LOCALE_NAME_USER_DEFAULT, 0, eptId.c_str(), -987, id, -987, NULL, NULL, 0);
|
||||
if (comparison - 2 == 0) {
|
||||
log_wdebugcpp("ola defaul de " << i << " es " << id);
|
||||
playbackDevices.at(j)->setRoles((1 << i));
|
||||
playbackDevices.at(j)->assignRoles((1 << i));
|
||||
}
|
||||
//uint8_t debg = playbackDevices.at(j)->getRoles();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Overseer::Overseer(){
|
||||
Overseer::Overseer() { //: epsc(deviceEnumerator, playbackDevices){
|
||||
//Initializing COM library
|
||||
log_debugcpp("Initializing Overseer");
|
||||
initCOMLibrary();
|
||||
|
||||
//Obtaining playback endpoint collection on this point in time
|
||||
reloadEndpoints();
|
||||
this->epsc.fill(deviceEnumerator, playbackDevices);
|
||||
if(FAILED(deviceEnumerator->RegisterEndpointNotificationCallback(((IMMNotificationClient*)&epsc)))) { log_debugcpp("when no enchufas......"); }
|
||||
}
|
||||
|
||||
//Overseer::int getDefaultPlaybackEndpoint(Endpoint** defaultEndpoint){
|
||||
//if (FAILED(deviceEnumerator->GetDefaultAudioEndpoint(eRender, eConsole, &endpointPtr)))
|
||||
// return 1;
|
||||
//return 0;
|
||||
//}
|
||||
|
||||
//int Overseer::getDefaultCaptureEndpoint(Endpoint** defaultEndpoint);
|
||||
|
||||
NGuid Overseer::getGuid() {
|
||||
return guid;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
//done by qt by def #define UNICODE
|
||||
|
||||
#include <Windows.h>
|
||||
#include <processthreadsapi.h>
|
||||
#include <mmdeviceapi.h>
|
||||
#include <combaseapi.h>
|
||||
#include <initguid.h>
|
||||
|
|
@ -41,7 +42,8 @@ class Endpoint {
|
|||
void setState(uint8_t state);
|
||||
uint8_t getState();
|
||||
uint8_t getRoles();
|
||||
void setRoles(uint8_t role);
|
||||
void setRoles(Roles role);
|
||||
void assignRoles(uint8_t role);
|
||||
std::wstring getId();
|
||||
std::wstring getName();
|
||||
void setVolumeCallback(EndpointVolumeCallback *epc);
|
||||
|
|
@ -77,6 +79,25 @@ class EndpointVolumeCallback : public IAudioEndpointVolumeCallback {
|
|||
Endpoint* ep;
|
||||
};
|
||||
|
||||
class EndpointSituationCallback : public IMMNotificationClient {
|
||||
public:
|
||||
//EndpointSituationCallback(IMMDeviceEnumerator *deviceEnumerator, std::vector<Endpoint*> playbackDevices);
|
||||
ULONG AddRef();
|
||||
ULONG Release();
|
||||
HRESULT QueryInterface(REFIID riid, VOID **ppvInterface);
|
||||
HRESULT OnDefaultDeviceChanged(EDataFlow flow, ERole role, LPCWSTR pwstrDeviceId);
|
||||
HRESULT OnDeviceAdded(LPCWSTR pwstrDeviceId);
|
||||
HRESULT OnDeviceRemoved(LPCWSTR pwstrDeviceId);
|
||||
HRESULT OnDeviceStateChanged(LPCWSTR pwstrDeviceId, DWORD dwNewState);
|
||||
HRESULT OnPropertyValueChanged(LPCWSTR pwstrDeviceId, const PROPERTYKEY key);
|
||||
|
||||
void fill(IMMDeviceEnumerator *deviceEnumerator, std::vector<Endpoint*> playbackDevices);
|
||||
private:
|
||||
ULONG ref = 1;
|
||||
IMMDeviceEnumerator *deviceEnumerator;
|
||||
std::vector<Endpoint*> playbackDevices;
|
||||
};
|
||||
|
||||
class Overseer {
|
||||
//TODO singleton?
|
||||
public:
|
||||
|
|
@ -84,6 +105,9 @@ class Overseer {
|
|||
std::vector<Endpoint*> getPlaybackEndpoints();
|
||||
void reloadEndpoints();
|
||||
NGuid getGuid();
|
||||
//void setEndpointStatusCallback();
|
||||
//void setEndpointStatusCallback();
|
||||
|
||||
//~Overseer();
|
||||
//int getDefaultPlaybackEndpoint(Endpoint** defaultEndpoint);
|
||||
//int getDefaultCaptureEndpoint(Endpoint** defaultEndpoint);
|
||||
|
|
@ -95,7 +119,8 @@ class Overseer {
|
|||
NGuid guid;
|
||||
unsigned int numPlaybackEndpoints;
|
||||
IMMDeviceEnumerator *deviceEnumerator;
|
||||
IPolicyConfig *policyConfig;
|
||||
EndpointSituationCallback epsc;
|
||||
//IPolicyConfig *policyConfig;
|
||||
std::vector<Endpoint*> playbackDevices;
|
||||
void initCOMLibrary();
|
||||
//IMMDeviceCollection *deviceCollection;
|
||||
|
|
|
|||
|
|
@ -70,6 +70,10 @@ uint8_t EndpointHandler::getRoles(){
|
|||
return ep->getRoles();
|
||||
}
|
||||
|
||||
void EndpointHandler::setRoles(Roles newRole){
|
||||
ep->setRoles(newRole);
|
||||
}
|
||||
|
||||
EndpointHandler::~EndpointHandler() {
|
||||
ep->removeVolumeCallback(epc);
|
||||
epc->Release();
|
||||
|
|
@ -118,6 +122,10 @@ NGuid OverseerHandler::getGuid() {
|
|||
return this->os->getGuid();
|
||||
}
|
||||
|
||||
void setChangeFrontDefaultsFunction(std::function<void(Roles, wchar* endpointId)> changeFrontDefaults){
|
||||
this->changeFrontDefaults = changeFrontDefaults;
|
||||
}
|
||||
|
||||
void OverseerHandler::setEndpointHandlers(std::vector<EndpointHandler*> ephs){
|
||||
this->endpointHandlers = ephs;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ enum EndpointState {
|
|||
ENDPOINT_DISABLED = (1 << 1),
|
||||
ENDPOINT_NOTPRESENT = (1 << 2),
|
||||
ENDPOINT_UNPLUGGED = (1 << 3),
|
||||
ENDPOINT_ALL = 0x0F
|
||||
};
|
||||
|
||||
enum Flows {
|
||||
|
|
@ -78,6 +79,7 @@ public:
|
|||
bool getMute();
|
||||
uint8_t getState();
|
||||
uint8_t getRoles();
|
||||
void setRoles(Roles newRole);
|
||||
|
||||
void setVolume(NGuid guid, int channel, int value);
|
||||
void setMute(NGuid guid, bool muted);
|
||||
|
|
@ -95,6 +97,7 @@ class OverseerHandler {
|
|||
|
||||
public:
|
||||
OverseerHandler();
|
||||
void setChangeFrontDefaultsFunction(std::function<void(Roles, wchar* endpointId)> changeFrontDefaults);
|
||||
void setEndpointHandlers(std::vector<EndpointHandler*> ephs);
|
||||
std::vector<EndpointHandler*> getEndpointHandlers();
|
||||
std::vector<Endpoint*> getPlaybackEndpoints();
|
||||
|
|
@ -105,7 +108,7 @@ public:
|
|||
private:
|
||||
Overseer *os;
|
||||
std::vector<EndpointHandler*> endpointHandlers;
|
||||
|
||||
std::function<void(Roles, wchar* endpointId)> changeFrontDefaults;
|
||||
//std::function<void(uint64_t /* device */, uint32_t /* channel */, float /* value */)> updateFrontVolumeCallback;
|
||||
//std::function<void(uint64_t /* device */, bool /* mute */)> updateFrontMuteCallback;
|
||||
|
||||
|
|
|
|||
|
|
@ -67,18 +67,39 @@ EndpointWidget::EndpointWidget(uint64_t idx, EndpointHandler* eph, QWidget *pare
|
|||
|
||||
uint8_t assignedRoles = eph->getRoles();
|
||||
defaultRolesCheckBoxes.at(Roles::ROLE_ALL)->setCheckState(assignedRoles == Roles::ROLE_ALL ? Qt::Checked : Qt::Unchecked);
|
||||
//todo duditas de &
|
||||
defaultRolesCheckBoxes.at(Roles::ROLE_ALL)->setDisabled(assignedRoles == Roles::ROLE_ALL ? true : false);
|
||||
defaultRolesCheckBoxes.at(Roles::ROLE_ALL)->setText(STRING_ROLE_ALL);
|
||||
|
||||
defaultRolesCheckBoxes.at(Roles::ROLE_CONSOLE)->setCheckState(assignedRoles & Roles::ROLE_CONSOLE ? Qt::Checked : Qt::Unchecked);
|
||||
defaultRolesCheckBoxes.at(Roles::ROLE_CONSOLE)->setDisabled(assignedRoles & Roles::ROLE_CONSOLE ? true : false);
|
||||
defaultRolesCheckBoxes.at(Roles::ROLE_CONSOLE)->setText(STRING_ROLE_CONSOLE);
|
||||
|
||||
defaultRolesCheckBoxes.at(Roles::ROLE_MULTIMEDIA)->setCheckState(assignedRoles & Roles::ROLE_MULTIMEDIA ? Qt::Checked : Qt::Unchecked);
|
||||
defaultRolesCheckBoxes.at(Roles::ROLE_MULTIMEDIA)->setDisabled(assignedRoles & Roles::ROLE_MULTIMEDIA ? true : false);
|
||||
defaultRolesCheckBoxes.at(Roles::ROLE_MULTIMEDIA)->setText(STRING_ROLE_MULTIMEDIA);
|
||||
|
||||
defaultRolesCheckBoxes.at(Roles::ROLE_COMMUNICATIONS)->setCheckState(assignedRoles & Roles::ROLE_COMMUNICATIONS ? Qt::Checked : Qt::Unchecked);
|
||||
defaultRolesCheckBoxes.at(Roles::ROLE_COMMUNICATIONS)->setDisabled(assignedRoles & Roles::ROLE_COMMUNICATIONS ? true : false);
|
||||
defaultRolesCheckBoxes.at(Roles::ROLE_COMMUNICATIONS)->setText(STRING_ROLE_COMMUNICATIONS);
|
||||
|
||||
connect(defaultRolesCheckBoxes.at(Roles::ROLE_ALL), &QCheckBox::stateChanged,[this] {
|
||||
this->eph->setRoles(Roles::ROLE_ALL);
|
||||
//todo: bloquiar pto
|
||||
});
|
||||
connect(defaultRolesCheckBoxes.at(Roles::ROLE_CONSOLE), &QCheckBox::stateChanged,[this] {
|
||||
this->eph->setRoles(Roles::ROLE_CONSOLE);
|
||||
//todo: bloquiar pto
|
||||
});
|
||||
connect(defaultRolesCheckBoxes.at(Roles::ROLE_MULTIMEDIA), &QCheckBox::stateChanged,[this] {
|
||||
this->eph->setRoles(Roles::ROLE_MULTIMEDIA);
|
||||
//todo: bloquiar pto
|
||||
});
|
||||
connect(defaultRolesCheckBoxes.at(Roles::ROLE_COMMUNICATIONS), &QCheckBox::stateChanged,[this] {
|
||||
this->eph->setRoles(Roles::ROLE_COMMUNICATIONS);
|
||||
//todo: bloquiar pto
|
||||
});
|
||||
|
||||
defaultRolesCheckBoxes.at(Roles::ROLE_ALL)->setText(STRING_ROLE_ALL);
|
||||
layout->addWidget(defaultRolesCheckBoxes.at(Roles::ROLE_ALL), 3, 0);
|
||||
layout->addWidget(defaultRolesCheckBoxes.at(Roles::ROLE_CONSOLE), 3, 1);
|
||||
layout->addWidget(defaultRolesCheckBoxes.at(Roles::ROLE_MULTIMEDIA), 3, 2);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue