enable/disable/add/remove groundwork done
This commit is contained in:
parent
a6a052f348
commit
04da76c021
4 changed files with 66 additions and 58 deletions
|
|
@ -71,14 +71,14 @@ HRESULT EndpointVolumeCallback::OnNotify(PAUDIO_VOLUME_NOTIFICATION_DATA pNotify
|
||||||
* this->deviceEnumerator = deviceEnumerator;
|
* this->deviceEnumerator = deviceEnumerator;
|
||||||
* this->playbackDevices = playbackDevices;
|
* this->playbackDevices = playbackDevices;
|
||||||
* }
|
* }
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
|
//todo: not on construct since it expects them to already exist; smells like refactor!
|
||||||
void EndpointSituationCallback::fill(IMMDeviceEnumerator *deviceEnumerator, std::vector<Endpoint*> playbackDevices){
|
void EndpointSituationCallback::fill(IMMDeviceEnumerator *deviceEnumerator, std::vector<Endpoint*> playbackDevices){
|
||||||
this->deviceEnumerator = deviceEnumerator;
|
this->deviceEnumerator = deviceEnumerator;
|
||||||
this->playbackDevices = playbackDevices;
|
this->playbackDevices = playbackDevices;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ULONG EndpointSituationCallback::AddRef(){
|
ULONG EndpointSituationCallback::AddRef(){
|
||||||
return InterlockedIncrement(&ref);
|
return InterlockedIncrement(&ref);
|
||||||
}
|
}
|
||||||
|
|
@ -132,36 +132,30 @@ HRESULT EndpointSituationCallback::OnDefaultDeviceChanged(EDataFlow flow, ERole
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT EndpointSituationCallback::OnDeviceAdded(LPCWSTR pwstrDeviceId) {
|
HRESULT EndpointSituationCallback::OnDeviceAdded(LPCWSTR pwstrDeviceId) {
|
||||||
|
log_wdebugcpp(L"ayo we eventing za adin" << pwstrDeviceId);
|
||||||
return S_OK;
|
return S_OK;
|
||||||
};
|
};
|
||||||
|
|
||||||
HRESULT EndpointSituationCallback::OnDeviceRemoved(LPCWSTR pwstrDeviceId) {
|
HRESULT EndpointSituationCallback::OnDeviceRemoved(LPCWSTR pwstrDeviceId) {
|
||||||
|
log_wdebugcpp(L"ayo we eventing za rmovin" << pwstrDeviceId);
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT EndpointSituationCallback::OnDeviceStateChanged(LPCWSTR pwstrDeviceId, DWORD dwNewState) {
|
HRESULT EndpointSituationCallback::OnDeviceStateChanged(LPCWSTR pwstrDeviceId, DWORD dwNewState) {
|
||||||
/*
|
switch (dwNewState){
|
||||||
* char *pszState = "?????";
|
case DEVICE_STATE_ACTIVE:
|
||||||
*
|
|
||||||
* switch (dwNewState)
|
break;
|
||||||
* {
|
case DEVICE_STATE_DISABLED:
|
||||||
* case DEVICE_STATE_ACTIVE:
|
|
||||||
* pszState = "ACTIVE";
|
break;
|
||||||
* break;
|
case DEVICE_STATE_NOTPRESENT:
|
||||||
* case DEVICE_STATE_DISABLED:
|
|
||||||
* pszState = "DISABLED";
|
break;
|
||||||
* break;
|
case DEVICE_STATE_UNPLUGGED:
|
||||||
* case DEVICE_STATE_NOTPRESENT:
|
|
||||||
* pszState = "NOTPRESENT";
|
break;
|
||||||
* 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;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
@ -184,6 +178,10 @@ Endpoint::Endpoint(IMMDevice* ep, uint64_t idx){
|
||||||
this->endpoint = ep;
|
this->endpoint = ep;
|
||||||
this->idx = idx;
|
this->idx = idx;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* It can't multiflag, it's that stupid. MS momento.
|
||||||
|
* Only shows most relevant flag according to MS, i.e. 0110 sends 0010
|
||||||
|
*/
|
||||||
//todo: preguntitas owindows dword no es uint32_t even tho mingw mingas
|
//todo: preguntitas owindows dword no es uint32_t even tho mingw mingas
|
||||||
if(FAILED(endpoint->GetState(&this->endpointState))) {exit(-1);};
|
if(FAILED(endpoint->GetState(&this->endpointState))) {exit(-1);};
|
||||||
|
|
||||||
|
|
@ -203,7 +201,10 @@ Endpoint::Endpoint(IMMDevice* ep, uint64_t idx){
|
||||||
endpoint->OpenPropertyStore(STGM_READ, &properties);
|
endpoint->OpenPropertyStore(STGM_READ, &properties);
|
||||||
PROPVARIANT pv;
|
PROPVARIANT pv;
|
||||||
properties->GetValue(PKEY_Device_FriendlyName , &pv);
|
properties->GetValue(PKEY_Device_FriendlyName , &pv);
|
||||||
friendlyName = std::wstring(pv.pwszVal);
|
if (pv.pwszVal == nullptr)
|
||||||
|
friendlyName = L"Unnamed Not Present Endpoint";
|
||||||
|
else
|
||||||
|
friendlyName = std::wstring(pv.pwszVal);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Endpoint::setIndex(uint64_t idx){
|
void Endpoint::setIndex(uint64_t idx){
|
||||||
|
|
@ -214,7 +215,6 @@ uint64_t Endpoint::getIndex(){
|
||||||
return idx;
|
return idx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
std::wstring Endpoint::getName(){
|
std::wstring Endpoint::getName(){
|
||||||
return friendlyName;
|
return friendlyName;
|
||||||
}
|
}
|
||||||
|
|
@ -253,14 +253,13 @@ size_t Endpoint::getState(){
|
||||||
return this->endpointState;
|
return this->endpointState;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Endpoint::setVolume(NGuid guid, int channel, float volume) {
|
void Endpoint::setVolume(NGuid guid, int channel, float volume) {
|
||||||
//TIP: There used to be log messages here. Now, it's a ghost town.
|
//TIP: There used to be log messages here. Now, it's a ghost town.
|
||||||
GUID tempMsGuid = NGuidToGUID(guid);
|
GUID tempMsGuid = NGuidToGUID(guid);
|
||||||
if (channel == AudioChannel::CHANNEL_MAIN) {
|
if (channel == AudioChannel::CHANNEL_MAIN) {
|
||||||
if(FAILED(endpointVolume->SetMasterVolumeLevelScalar(volume, &tempMsGuid))) {};
|
if(FAILED(endpointVolume->SetMasterVolumeLevelScalar(volume, &tempMsGuid))) {};
|
||||||
} else {
|
} else {
|
||||||
if(FAILED(endpointVolume->SetChannelVolumeLevelScalar(channel, volume, &tempMsGuid))) { };
|
if(FAILED(endpointVolume->SetChannelVolumeLevelScalar(channel, volume, &tempMsGuid))) {};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -391,7 +390,8 @@ void Overseer::initCOMLibrary() {
|
||||||
void Overseer::reloadEndpoints() {
|
void Overseer::reloadEndpoints() {
|
||||||
IMMDeviceCollection *deviceCollection;
|
IMMDeviceCollection *deviceCollection;
|
||||||
// | DEVICE_STATE_DISABLED | DEVICE_STATE_NOTPRESENT | DEVICE_STATE_UNPLUGGED
|
// | DEVICE_STATE_DISABLED | DEVICE_STATE_NOTPRESENT | DEVICE_STATE_UNPLUGGED
|
||||||
if(FAILED(deviceEnumerator->EnumAudioEndpoints(eRender, DEVICE_STATE_ACTIVE, &deviceCollection) ))
|
// NOTPRESENT shows a lot of garbage, unnamed devices.
|
||||||
|
if(FAILED(deviceEnumerator->EnumAudioEndpoints(eRender, DEVICE_STATE_ACTIVE | DEVICE_STATE_DISABLED, &deviceCollection) ))
|
||||||
{ log_debugcpp("si"); };
|
{ log_debugcpp("si"); };
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
||||||
|
|
@ -61,7 +61,6 @@ class Endpoint {
|
||||||
unsigned long endpointState;
|
unsigned long endpointState;
|
||||||
uint8_t endpointRoles = 0;
|
uint8_t endpointRoles = 0;
|
||||||
uint64_t idx;
|
uint64_t idx;
|
||||||
// LPWSTR endpointID = NULL;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class EndpointVolumeCallback : public IAudioEndpointVolumeCallback {
|
class EndpointVolumeCallback : public IAudioEndpointVolumeCallback {
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
#include "qtclasses.h"
|
#include "qtclasses.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool ExtendedCheckBox::event(QEvent* ev) {
|
bool ExtendedCheckBox::event(QEvent* ev) {
|
||||||
if (ev->type() == QEvent::User) {
|
if (ev->type() == QEvent::User) {
|
||||||
this->blockSignals(true);
|
this->blockSignals(true);
|
||||||
|
|
@ -20,26 +21,27 @@ bool ExtendedCheckBox::event(QEvent* ev) {
|
||||||
|
|
||||||
|
|
||||||
EndpointWidget::EndpointWidget(uint64_t idx, EndpointHandler* eph, QWidget *parent) : QWidget(parent){
|
EndpointWidget::EndpointWidget(uint64_t idx, EndpointHandler* eph, QWidget *parent) : QWidget(parent){
|
||||||
|
//todo: based on qgridlayout, name+mute should be its own widget, same with channels
|
||||||
this->idx = idx;
|
this->idx = idx;
|
||||||
this->eph = eph;
|
this->eph = eph;
|
||||||
layout = new QGridLayout();
|
layout = new QGridLayout(this);
|
||||||
this->setLayout(layout);
|
//this->setLayout(layout);
|
||||||
log_debugcpp("olaW");
|
log_debugcpp("epw main layout parent: "<< layout->parent());
|
||||||
if (parent == nullptr) { log_debugcpp("owo?"); }
|
if (parent == nullptr) { log_debugcpp("owo?"); }
|
||||||
|
|
||||||
defaultRolesCheckBoxes = {
|
defaultRolesCheckBoxes = {
|
||||||
{Roles::ROLE_ALL, new ExtendedCheckBox()},
|
{Roles::ROLE_ALL, new ExtendedCheckBox(this)},
|
||||||
{Roles::ROLE_CONSOLE, new ExtendedCheckBox()},
|
{Roles::ROLE_CONSOLE, new ExtendedCheckBox(this)},
|
||||||
{Roles::ROLE_MULTIMEDIA, new ExtendedCheckBox()},
|
{Roles::ROLE_MULTIMEDIA, new ExtendedCheckBox(this)},
|
||||||
{Roles::ROLE_COMMUNICATIONS, new ExtendedCheckBox()}
|
{Roles::ROLE_COMMUNICATIONS, new ExtendedCheckBox(this)}
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Mute, main slider and label setup
|
* Mute, main slider and label setup
|
||||||
*/
|
*/
|
||||||
muteButton = new QCheckBox();
|
muteButton = new QCheckBox(this);
|
||||||
mainLabel = new QLabel(QString::fromStdWString(eph->getName()));
|
mainLabel = new QLabel(QString::fromStdWString(eph->getName()), this);
|
||||||
mainSlider = new QSlider(Qt::Horizontal);
|
mainSlider = new QSlider(Qt::Horizontal, this);
|
||||||
|
|
||||||
if (this->eph->getState() != EndpointState::ENDPOINT_ACTIVE) {
|
if (this->eph->getState() != EndpointState::ENDPOINT_ACTIVE) {
|
||||||
layout->addWidget(mainLabel, 0, 0);
|
layout->addWidget(mainLabel, 0, 0);
|
||||||
|
|
@ -48,6 +50,7 @@ EndpointWidget::EndpointWidget(uint64_t idx, EndpointHandler* eph, QWidget *pare
|
||||||
}
|
}
|
||||||
|
|
||||||
//muteButton->setStyleSheet("background-color: #A3C1DA; color: red");
|
//muteButton->setStyleSheet("background-color: #A3C1DA; color: red");
|
||||||
|
mainSlider->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
||||||
mainSlider->setFocusPolicy(Qt::StrongFocus);
|
mainSlider->setFocusPolicy(Qt::StrongFocus);
|
||||||
mainSlider->setTickPosition(QSlider::TicksBothSides);
|
mainSlider->setTickPosition(QSlider::TicksBothSides);
|
||||||
mainSlider->setTickInterval(5);
|
mainSlider->setTickInterval(5);
|
||||||
|
|
@ -60,12 +63,11 @@ EndpointWidget::EndpointWidget(uint64_t idx, EndpointHandler* eph, QWidget *pare
|
||||||
mainSlider->setValue((int)volume);
|
mainSlider->setValue((int)volume);
|
||||||
log_debugcpp("ENDPOINT SET WITH VOLUME " << volume);
|
log_debugcpp("ENDPOINT SET WITH VOLUME " << volume);
|
||||||
|
|
||||||
//todo: parent
|
//tip: would need to be new widget with layout in it
|
||||||
mainMuteLayout = new QGridLayout();
|
//mainMuteLayout = new QGridLayout();
|
||||||
layout->addLayout(mainMuteLayout, 0, 0, 2, 1, Qt::AlignLeft | Qt::AlignBottom);
|
layout->addWidget(mainLabel, 0, 0, Qt::AlignLeft | Qt::AlignBottom);
|
||||||
mainMuteLayout->addWidget(mainLabel, 0, 0);
|
layout->addWidget(muteButton, 0, 1, Qt::AlignLeft | Qt::AlignBottom);
|
||||||
mainMuteLayout->addWidget(muteButton, 0, 1);
|
layout->addWidget(mainSlider, 0, 2, 1, 2);
|
||||||
layout->addWidget(mainSlider, 0, 2, 1, 2, Qt::AlignLeft | Qt::AlignBottom);
|
|
||||||
|
|
||||||
//TODO:0 = mute and muted, change volume = unmuted are client side tricks = 2 callbacks, one for volume, one for mute state. Implement as an user selectable option?
|
//TODO:0 = mute and muted, change volume = unmuted are client side tricks = 2 callbacks, one for volume, one for mute state. Implement as an user selectable option?
|
||||||
connect<void(QSlider::*)(int), void(EndpointWidget::*)(int)>(mainSlider, &QSlider::valueChanged, this,&EndpointWidget::updateMainVolume);
|
connect<void(QSlider::*)(int), void(EndpointWidget::*)(int)>(mainSlider, &QSlider::valueChanged, this,&EndpointWidget::updateMainVolume);
|
||||||
|
|
@ -78,6 +80,7 @@ EndpointWidget::EndpointWidget(uint64_t idx, EndpointHandler* eph, QWidget *pare
|
||||||
for(uint32_t i = 0; i < eph->getChannelCount(); i++){
|
for(uint32_t i = 0; i < eph->getChannelCount(); i++){
|
||||||
QSlider* tmp = new QSlider(Qt::Horizontal);
|
QSlider* tmp = new QSlider(Qt::Horizontal);
|
||||||
QLabel* tmpLb = new QLabel("");
|
QLabel* tmpLb = new QLabel("");
|
||||||
|
tmp->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
||||||
tmp->setTickInterval(5);
|
tmp->setTickInterval(5);
|
||||||
tmp->setSingleStep(1);
|
tmp->setSingleStep(1);
|
||||||
tmp->setRange(0,100);
|
tmp->setRange(0,100);
|
||||||
|
|
@ -87,8 +90,8 @@ EndpointWidget::EndpointWidget(uint64_t idx, EndpointHandler* eph, QWidget *pare
|
||||||
tmpLb->setText(QString::number(volume));
|
tmpLb->setText(QString::number(volume));
|
||||||
this->channelSliders.push_back(tmp);
|
this->channelSliders.push_back(tmp);
|
||||||
this->channelLabels.push_back(tmpLb);
|
this->channelLabels.push_back(tmpLb);
|
||||||
layout->addWidget(tmp, 2, i, 1, 2, Qt::AlignLeft | Qt::AlignTop);
|
layout->addWidget(tmp, 2, i);
|
||||||
layout->addWidget(tmpLb, 3, i, 1, 2, Qt::AlignLeft | Qt::AlignTop);
|
layout->addWidget(tmpLb, 3, i);
|
||||||
//TODO: check if there's a need to prevent deadlocks; probably this will eventually turn into its own func
|
//TODO: check if there's a need to prevent deadlocks; probably this will eventually turn into its own func
|
||||||
//this causes channel bar desync when back -> front. blocksignals below fix it. huh.
|
//this causes channel bar desync when back -> front. blocksignals below fix it. huh.
|
||||||
connect(tmp, &QSlider::valueChanged, [this, i](int newValue){
|
connect(tmp, &QSlider::valueChanged, [this, i](int newValue){
|
||||||
|
|
@ -329,16 +332,18 @@ void MainWindow::trayIconActivated(QSystemTrayIcon::ActivationReason reason) {
|
||||||
|
|
||||||
void MainWindow::reloadEndpointWidgets() {
|
void MainWindow::reloadEndpointWidgets() {
|
||||||
size_t i = 0;
|
size_t i = 0;
|
||||||
for (; i < (osh->getEndpointHandlers().size()); i++) {
|
for (size_t epwIndex = 0; i < (osh->getEndpointHandlers().size()); i++) {
|
||||||
log_debugcpp("EPWidget creation");
|
if (osh->getEndpointHandlers().at(i)->getState() == EndpointState::ENDPOINT_ACTIVE){
|
||||||
osh->getEndpointHandlers().at(i)->getCallbackInfo()->caller = osh->getGuid();
|
log_debugcpp("EPWidget creation");
|
||||||
EndpointWidget *epw = new EndpointWidget(i, osh->getEndpointHandlers().at(i), widget);
|
osh->getEndpointHandlers().at(i)->getCallbackInfo()->caller = osh->getGuid();
|
||||||
//TODO: ALWAYS PUSH BACK??? PSZ CHANGE DIS WHEN IMPLEMENTING DYN ENDPOINT DET
|
EndpointWidget *epw = new EndpointWidget(epwIndex, osh->getEndpointHandlers().at(i), widget);
|
||||||
ews.push_back(epw);
|
epwIndex++;
|
||||||
layout->addWidget(epw, i, 0);
|
//TODO: ALWAYS PUSH BACK??? PSZ CHANGE DIS WHEN IMPLEMENTING DYN ENDPOINT DET
|
||||||
|
ews.push_back(epw);
|
||||||
|
layout->addWidget(epw, i, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
//todo:: tas aqui tirao, no me gustas y probablemente yo a ti tampoco
|
||||||
layout->addItem(new QSpacerItem(1, 1, QSizePolicy::Minimum, QSizePolicy::MinimumExpanding), i, 0);
|
layout->addItem(new QSpacerItem(1, 1, QSizePolicy::Minimum, QSizePolicy::MinimumExpanding), i, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -61,6 +61,10 @@
|
||||||
class ExtendedCheckBox : public QCheckBox {
|
class ExtendedCheckBox : public QCheckBox {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
|
//c++11: this inherits all parent's constructors unconditionally
|
||||||
|
using QCheckBox::QCheckBox;
|
||||||
|
//alternative being calling parent ctor directly after declaring child ctor:
|
||||||
|
//B(int x) : A(x) { }
|
||||||
bool event(QEvent* ev) override;
|
bool event(QEvent* ev) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue