session baby steps

This commit is contained in:
Hane 2023-09-18 23:37:06 +02:00
commit 6d88697811
14 changed files with 393 additions and 87 deletions

View file

@ -9,8 +9,8 @@ QT += widgets network
INCLUDEPATH += "$$PWD\src" "$$PWD\src\qt" "$$PWD\src\back" "$$PWD\src\cont" INCLUDEPATH += "$$PWD\src" "$$PWD\src\qt" "$$PWD\src\back" "$$PWD\src\cont"
DESTPATH += "$$PWD\src" "$$PWD\src\qt" "$$PWD\src\back" "$$PWD\src\cont" DESTPATH += "$$PWD\src" "$$PWD\src\qt" "$$PWD\src\back" "$$PWD\src\cont"
VPATH += "$$PWD\src" "$$PWD\src\qt" "$$PWD\src\back" "$$PWD\src\cont" VPATH += "$$PWD\src" "$$PWD\src\qt" "$$PWD\src\back" "$$PWD\src\cont"
SOURCES += qtestmain.cpp qtclasses.cpp backlasses.cpp contclasses.cpp SOURCES += qtestmain.cpp qtclasses.cpp backlasses.cpp backsessionclasses.cpp contclasses.cpp contsessionclasses.cpp
HEADERS += qtclasses.h backlasses.h contclasses.h global.h debug.h backfuncs.h ipolicyconfig.h HEADERS += qtclasses.h backlasses.h backsessionclasses.h contclasses.h contsessionclasses.h global.h debug.h backfuncs.h ipolicyconfig.h msinclude.h
RESOURCES = assets.qrc RESOURCES = assets.qrc
#DESTDIR += "build" #DESTDIR += "build"

View file

@ -1,4 +1,4 @@
GUID NGuidToGUID(NGuid guid) { GUID inline NGuidToGUID(NGuid guid) {
GUID msGuid = GUID(); GUID msGuid = GUID();
msGuid.Data1 = guid.data1; msGuid.Data1 = guid.data1;
msGuid.Data2 = guid.data2; msGuid.Data2 = guid.data2;
@ -15,7 +15,7 @@ GUID NGuidToGUID(NGuid guid) {
return msGuid; return msGuid;
} }
NGuid GUIDToNGuid(LPGUID msGuid){ NGuid inline GUIDToNGuid(LPGUID msGuid){
NGuid guid = NGuid(); NGuid guid = NGuid();
guid.data1 = msGuid->Data1; guid.data1 = msGuid->Data1;
guid.data2 = msGuid->Data2; guid.data2 = msGuid->Data2;

View file

@ -207,7 +207,7 @@ Endpoint::Endpoint(IMMDevice* ep, uint64_t idx){
reloadEndpointChannels(); reloadEndpointChannels();
/* /* todo: check header
* if(FAILED(endpoint->Activate(__uuidof(IAudioMeterInformation), * if(FAILED(endpoint->Activate(__uuidof(IAudioMeterInformation),
* CLSCTX_ALL, NULL, (void**)&endpointPeakMeter))) { log_debugcpp("peakbros..."); } * CLSCTX_ALL, NULL, (void**)&endpointPeakMeter))) { log_debugcpp("peakbros..."); }
*/ */
@ -228,12 +228,37 @@ Endpoint::Endpoint(IMMDevice* ep, uint64_t idx){
friendlyName = std::wstring(pv.pwszVal); friendlyName = std::wstring(pv.pwszVal);
this->setFlow(); this->setFlow();
if (this->endpointState == EndpointState::ENDPOINT_ACTIVE && this->flow == Flows::FLOW_PLAYBACK) {
activateEndpointSessions();
}
} }
/* /*
* Endpoint::Endpoint(IMMDevice* endpoint) : Endpoint(endpoint, 0) {}; * Endpoint::Endpoint(IMMDevice* endpoint) : Endpoint(endpoint, 0) {};
*/ */
void Endpoint::activateEndpointSessions() {
//sessionManager;
if (FAILED(endpoint->Activate(__uuidof(IAudioSessionManager2), CLSCTX_ALL, NULL, (void**) &sessionManager))) { log_wdebugcpp(L"sesionbros..."); return; }
IAudioSessionEnumerator* sessionEnumerator = nullptr;
if (FAILED(sessionManager->GetSessionEnumerator(&sessionEnumerator))) { log_wdebugcpp(L"sesEnumeratorBros..."); return; }
int sessionCount;
sessionEnumerator->GetCount(&sessionCount);
for (int i = 0; i < sessionCount; i++) {
IAudioSessionControl* sessionControlTmp;
sessionEnumerator->GetSession(i, (IAudioSessionControl**)&sessionControlTmp);
//todo:: asegurar lo del dynamic_cast
IAudioSessionControl2* sessionControl;
sessionControlTmp->QueryInterface(__uuidof(IAudioSessionControl2), (void**)&sessionControl);
sessionControl->AddRef();
sessionControlTmp->Release();
Session* session = new Session(this, sessionControl, (size_t)i);
endpointSessions.push_back(session);
}
sessionEnumerator->Release();
}
void Endpoint::activateEndpointVolume() { void Endpoint::activateEndpointVolume() {
//bool extraThread = false; //bool extraThread = false;
@ -444,11 +469,21 @@ Flows Endpoint::getFlow() {
return this->flow; return this->flow;
} }
/* sessions */
std::vector<Session*> Endpoint::getSessions() {
return endpointSessions;
}
size_t Endpoint::getSessionCount() {
return endpointSessions.size();
}
Endpoint::~Endpoint(){ Endpoint::~Endpoint(){
log_debugcpp("murio endpoint-san uwu"); log_wdebugcpp(L"murio endpoint-san uwu");
properties->Release(); properties->Release();
endpointVolume->Release(); endpointVolume->Release();
endpoint->Release(); endpoint->Release();
sessionManager->Release();
} }
void Overseer::initCOMLibrary() { void Overseer::initCOMLibrary() {

View file

@ -1,33 +1,12 @@
#pragma once #pragma once
#define _WIN32_WINNT 0x0A00 #include "msinclude.h"
#include <sdkddkver.h> #include "backsessionclasses.h"
//done by qt by def #define UNICODE
#include <Windows.h>
#include <processthreadsapi.h>
#include <mmdeviceapi.h>
#include <combaseapi.h>
#include <initguid.h>
#include <Propidl.h>
#include <functiondiscoverykeys_devpkey.h>
//#include <debugapi.h>
#include <endpointvolume.h>
#include <audiopolicy.h>
#include <audioclient.h>
//#include <comdef.h>
//#include <comip.h>
#include <Winerror.h>
#include <stringapiset.h>
#include "ipolicyconfig.h"
#include <Mmreg.h>
#include "global.h" #include "global.h"
#include "contclasses.h" #include "contclasses.h"
class EndpointVolumeCallback; class EndpointVolumeCallback;
class Session;
class Endpoint { class Endpoint {
@ -53,15 +32,25 @@ class Endpoint {
Flows getFlow(); Flows getFlow();
std::wstring getId(); std::wstring getId();
std::wstring getName(); std::wstring getName();
void setVolumeCallback(EndpointVolumeCallback *epc); void setVolumeCallback(EndpointVolumeCallback *epc);
void removeVolumeCallback(EndpointVolumeCallback *epc); void removeVolumeCallback(EndpointVolumeCallback *epc);
/* sessions */
std::vector<Session*> getSessions();
size_t getSessionCount();
~Endpoint(); ~Endpoint();
private: private:
void inline activateEndpointVolume(); void inline activateEndpointVolume();
void inline activateEndpointSessions();
std::vector<Session*> endpointSessions;
uint32_t channelCount = 0; uint32_t channelCount = 0;
IMMDevice* endpoint; IMMDevice* endpoint;
IAudioSessionManager2 *sessionManager;
Flows flow; Flows flow;
IAudioEndpointVolume *endpointVolume = nullptr; IAudioEndpointVolume *endpointVolume = nullptr;
IPropertyStore *properties; IPropertyStore *properties;

View file

@ -0,0 +1,62 @@
#include "backsessionclasses.h"
#include "backfuncs.h"
Session::Session(Endpoint* ep, IAudioSessionControl2* sessionControl, size_t idx) {
this->ep = ep;
this->sessionControl = sessionControl;
this->idx = idx;
sessionControl->QueryInterface(__uuidof(ISimpleAudioVolume), (void**)&sessionVolume);
DWORD pid;
sessionControl->GetProcessId(&pid);
if (sessionControl->IsSystemSoundsSession() == S_OK)
this->sessionName = std::wstring(LSTRING_SYSTEM_SOUNDS);
else {
LPWSTR sessionDisplayName;
this->sessionControl->GetDisplayName(&sessionDisplayName);
this->sessionName = std::wstring(sessionDisplayName);
CoTaskMemFree(sessionDisplayName);
}
}
float Session::getVolume(int channel){
float volume;
if (channel == AudioChannel::CHANNEL_MAIN) {
if(FAILED(sessionVolume->GetMasterVolume(&volume))) { /* log_debugcpp("si") */;}
} else {
return 0.0;
//if(FAILED(endpointVolume->GetChannelVolumeLevelScalar(channel, &volume))) { /* log_debugcpp("si"); */}
}
return volume;
}
/*
* uint32_t Endpoint::getChannelCount(){
* return (uint32_t)channelCount;
* }
*/
std::wstring Session::getName() {
return sessionName;
}
bool Session::getMute() {
BOOL mut;
if(FAILED(sessionVolume->GetMute(&mut))) { /* TIP: Below */ }
bool mute = (bool)mut;
return mute;
}
void Session::setVolume(NGuid guid, int channel, float volume) {
//TIP: There used to be log messages here. Now, it's a ghost town.
GUID tempMsGuid = NGuidToGUID(guid);
if (channel == AudioChannel::CHANNEL_MAIN) {
if(FAILED(sessionVolume->SetMasterVolume(volume, &tempMsGuid))) {};
} else {
//if(FAILED(sessionVolume->SetChannelVolumeLevelScalar(channel, volume, &tempMsGuid))) {};
}
}
void Session::setMute(NGuid guid, bool muted) {
GUID tempMsGuid = NGuidToGUID(guid);
if(FAILED(sessionVolume->SetMute(muted, &tempMsGuid))) { log_wdebugcpp(std::wstring(L"SessionVolume null?")); };
}

View file

@ -0,0 +1,26 @@
#pragma once
#include "msinclude.h"
#include "global.h"
#include "contclasses.h"
class Endpoint;
class Session {
public:
Session(Endpoint* ep, IAudioSessionControl2* sessionControl, size_t idx);
void setVolume(NGuid guid, int channel, float volume);
float getVolume(int channel);
void setMute(NGuid guid, bool muted);
bool getMute();
std::wstring getName();
//uint32_t getChannelCount();
private:
std::wstring sessionName;
Endpoint* ep;
IAudioSessionControl2* sessionControl = nullptr;
ISimpleAudioVolume* sessionVolume = nullptr;
size_t idx;
};

25
src/back/msinclude.h Normal file
View file

@ -0,0 +1,25 @@
#pragma once
#define _WIN32_WINNT 0x0A00
#include <sdkddkver.h>
//done by qt by def #define UNICODE
#include <Windows.h>
#include <processthreadsapi.h>
#include <mmdeviceapi.h>
#include <combaseapi.h>
#include <initguid.h>
#include <Propidl.h>
#include <functiondiscoverykeys_devpkey.h>
//#include <debugapi.h>
#include <endpointvolume.h>
#include <audiopolicy.h>
#include <audioclient.h>
//#include <comdef.h>
//#include <comip.h>
#include <Winerror.h>
#include <stringapiset.h>
#include "ipolicyconfig.h"
#include <Mmreg.h>

View file

@ -14,6 +14,14 @@ EndpointHandler::EndpointHandler(uint64_t idx, Flows flow) {
//epName = ep->getName(); //epName = ep->getName();
this->setBackEndpointVolumeCallbackInfoContent(this->getState()); this->setBackEndpointVolumeCallbackInfoContent(this->getState());
osh->pushBackEndpointHandler(this, flow); osh->pushBackEndpointHandler(this, flow);
if (this->flow == Flows::FLOW_PLAYBACK && this->getState() == EndpointState::ENDPOINT_ACTIVE) {
for (int i = 0; i < this->getSessionCount(); i++) {
SessionHandler* sessionHandler = new SessionHandler(this, this->getSessions().at(i),i);
sessionHandlers.push_back(sessionHandler);
}
}
} }
void OverseerHandler::pushBackEndpointHandler(EndpointHandler* eph, Flows flow) { void OverseerHandler::pushBackEndpointHandler(EndpointHandler* eph, Flows flow) {
@ -141,6 +149,19 @@ void EndpointHandler::removeRoles(Roles newRole){
ep->removeRoles(newRole); ep->removeRoles(newRole);
} }
/* sessions */
size_t EndpointHandler::getSessionCount() {
return ep->getSessionCount();
}
std::vector<Session*> EndpointHandler::getSessions(){
return ep->getSessions();
}
std::vector<SessionHandler*> EndpointHandler::getSessionHandlers(){
return this->sessionHandlers;
}
EndpointHandler::~EndpointHandler() { EndpointHandler::~EndpointHandler() {
ep->removeVolumeCallback(epc); ep->removeVolumeCallback(epc);
epc->Release(); epc->Release();

View file

@ -1,4 +1,7 @@
#pragma once #pragma once
#include "global.h"
#include "contsessionclasses.h"
//#define invoke_mem_fn(object,ptrToMember) ((object).*(ptrToMember)) //#define invoke_mem_fn(object,ptrToMember) ((object).*(ptrToMember))
//#define pinvoke_mem_fn(object,ptrToMember) ((object)->*(ptrToMember)) //#define pinvoke_mem_fn(object,ptrToMember) ((object)->*(ptrToMember))
@ -6,50 +9,7 @@ class EndpointWidget;
class Endpoint; class Endpoint;
class EndpointVolumeCallback; class EndpointVolumeCallback;
class Overseer; class Overseer;
class SessionHandler;
enum AudioChannel {
CHANNEL_LEFT = (1 << 0),
CHANNEL_RIGHT = (1 << 1),
CHANNEL_MAIN = ~0,
};
enum EndpointState {
ENDPOINT_ACTIVE = (1 << 0),
ENDPOINT_DISABLED = (1 << 1),
ENDPOINT_NOTPRESENT = (1 << 2),
ENDPOINT_UNPLUGGED = (1 << 3),
ENDPOINT_ALL = 0x0F
};
enum Flows {
FLOW_PLAYBACK = (1 << 0),
FLOW_CAPTURE = (1 << 1),
FLOW_BOTH = (1 << 2),
};
enum Roles {
ROLE_CONSOLE = (1 << 0),
ROLE_MULTIMEDIA = (1 << 1),
ROLE_COMMUNICATIONS = (1 << 2),
ROLE_ALL = 0x07,
};
struct NGuid {
//todo: still leaking?
uint32_t data1;
uint16_t data2;
uint16_t data3;
unsigned char data4[8];
/* void freeData4(){ */
/* int i = 0; */
/* do{ */
/* if(this->data4 + i != nullptr) free(data4 + i); */
/* i++; */
/* }while (i < 8); */
/* } */
};
struct BackEndpointVolumeCallbackInfo { struct BackEndpointVolumeCallbackInfo {
NGuid caller; NGuid caller;
@ -98,8 +58,14 @@ public:
void setState(uint8_t state); void setState(uint8_t state);
void setState(uint8_t state, uint64_t idx); void setState(uint8_t state, uint64_t idx);
/* sessions */
size_t getSessionCount();
std::vector<SessionHandler*> getSessionHandlers();
~EndpointHandler(); ~EndpointHandler();
private: private:
std::vector<Session*> getSessions();
uint64_t idx; uint64_t idx;
Endpoint *ep = nullptr; Endpoint *ep = nullptr;
EndpointVolumeCallback *epc = nullptr; EndpointVolumeCallback *epc = nullptr;
@ -110,6 +76,7 @@ private:
uint64_t frontIdx = INT_MAX; uint64_t frontIdx = INT_MAX;
}; };
EndpointHandlerFrontVisibility ephfv; EndpointHandlerFrontVisibility ephfv;
std::vector<SessionHandler*> sessionHandlers;
//QSlider *slidy; //QSlider *slidy;
}; };

View file

@ -0,0 +1,30 @@
#include "contsessionclasses.h"
#include "backsessionclasses.h"
SessionHandler::SessionHandler(EndpointHandler* eph, Session* session, size_t idx) {
this->eph = eph;
this->idx = idx;
this->session = session;
}
void SessionHandler::setVolume(NGuid guid, int channel, int value){
if (channel == AudioChannel::CHANNEL_MAIN)
session->setVolume(guid, channel, (float)value / 100);
else session->setVolume(guid, channel, (float)value / 100);
}
float SessionHandler::getVolume(int channel){
return session->getVolume(channel);
}
void SessionHandler::setMute(NGuid guid, bool muted){
session->setMute(guid, muted);
}
std::wstring SessionHandler::getName(){
return session->getName();
}
bool SessionHandler::getMute(){
return session->getMute();
}

View file

@ -0,0 +1,23 @@
#pragma once
#include "global.h"
//#include "contclasses.h"
class EndpointHandler;
class Session;
class SessionHandler {
public:
SessionHandler(EndpointHandler* eph, Session* session, size_t idx);
void setVolume(NGuid guid, int channel, int value);
float getVolume(int channel);
void setMute(NGuid guid, bool muted);
bool getMute();
std::wstring getName();
private:
EndpointHandler* eph;
Session* session;
size_t idx;
};

View file

@ -18,8 +18,56 @@
#define STRING_ROLE_MULTIMEDIA "Multimedia" #define STRING_ROLE_MULTIMEDIA "Multimedia"
#define STRING_ROLE_COMMUNICATIONS "Communications" #define STRING_ROLE_COMMUNICATIONS "Communications"
#define STRING_ROLE_ALL "All" #define STRING_ROLE_ALL "All"
#define STRING_SYSTEM_SOUNDS "System Sounds"
#define LSTRING_SYSTEM_SOUNDS L"System Sounds"
//INIT BACK //INIT BACK
enum AudioChannel {
CHANNEL_LEFT = (1 << 0),
CHANNEL_RIGHT = (1 << 1),
CHANNEL_MAIN = ~0,
};
enum EndpointState {
ENDPOINT_ACTIVE = (1 << 0),
ENDPOINT_DISABLED = (1 << 1),
ENDPOINT_NOTPRESENT = (1 << 2),
ENDPOINT_UNPLUGGED = (1 << 3),
ENDPOINT_ALL = 0x0F
};
enum Flows {
FLOW_PLAYBACK = (1 << 0),
FLOW_CAPTURE = (1 << 1),
FLOW_BOTH = (1 << 2),
};
enum Roles {
ROLE_CONSOLE = (1 << 0),
ROLE_MULTIMEDIA = (1 << 1),
ROLE_COMMUNICATIONS = (1 << 2),
ROLE_ALL = 0x07,
};
struct NGuid {
//todo: still leaking?
uint32_t data1;
uint16_t data2;
uint16_t data3;
unsigned char data4[8];
/* void freeData4(){ */
/* int i = 0; */
/* do{ */
/* if(this->data4 + i != nullptr) free(data4 + i); */
/* i++; */
/* }while (i < 8); */
/* } */
};
class OverseerHandler; class OverseerHandler;
extern OverseerHandler *osh; extern OverseerHandler *osh;

View file

@ -25,8 +25,56 @@ void ExtendedCheckBox::customEvent(QEvent* ev) {
QCheckBox::customEvent(ev); QCheckBox::customEvent(ev);
} }
SessionWidget::SessionWidget(uint64_t idx, SessionHandler* sh, QWidget *parent) : QWidget(parent){
//todo: based on qgridlayout, name+mute should be its own widget, same with channels
this->idx = idx;
this->sh = sh;
layout = new QGridLayout(this);
//this->setLayout(
muteButton = new QCheckBox(this);
mainLabel = new QLabel(QString::fromStdWString(sh->getName()), this);
mainSlider = new QSlider(Qt::Horizontal, this);
mainSlider->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
mainSlider->setFocusPolicy(Qt::StrongFocus);
mainSlider->setTickPosition(QSlider::TicksBothSides);
mainSlider->setTickInterval(5);
mainSlider->setSingleStep(1);
mainSlider->setRange(0,100);
muteButton->setCheckState((sh->getMute() == false ? Qt::Unchecked : Qt::Checked));
muteButton->setText(sh->getMute() ? STRING_UNMUTE : STRING_MUTE);
float volume = sh->getVolume(AudioChannel::CHANNEL_MAIN) * 100;
mainSlider->setValue((int)volume);
log_debugcpp("SESSION SET WITH VOLUME " + std::to_string(volume));
//tip: would need to be new widget with layout in it
//mainMuteLayout = new QGridLayout();
layout->addWidget(mainLabel, 0, 0, Qt::AlignLeft | Qt::AlignBottom);
layout->addWidget(muteButton, 0, 1, Qt::AlignLeft | Qt::AlignBottom);
layout->addWidget(mainSlider, 0, 2, 1, 2);
//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(SessionWidget::*)(int)>(mainSlider, &QSlider::valueChanged, this,&SessionWidget::updateMainVolume);
connect<void(QCheckBox::*)(int), void(SessionWidget::*)(int)>(muteButton, &QCheckBox::stateChanged, this, (&SessionWidget::updateMute));
}
void SessionWidget::updateMute(int checked){
bool muted = (checked == 2 ? true : false);
this->sh->setMute(osh->getGuid(), muted);
this->muteButton->setText(this->sh->getMute() ? STRING_UNMUTE : STRING_MUTE);
}
void SessionWidget::updateMainVolume(int newValue){
this->sh->setVolume(osh->getGuid(), AudioChannel::CHANNEL_MAIN, newValue);
}
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 //todo: based on qgridlayout, name+mute should be its own widget, same with channels
int row = 0;
this->idx = idx; this->idx = idx;
this->eph = eph; this->eph = eph;
//todo: sussy //todo: sussy
@ -52,7 +100,7 @@ EndpointWidget::EndpointWidget(uint64_t idx, EndpointHandler* eph, QWidget *pare
mainSlider = new QSlider(Qt::Horizontal, this); 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, row, 0);
layout->addItem(new QSpacerItem(1, 1, QSizePolicy::Minimum, QSizePolicy::Minimum), 1, 0); layout->addItem(new QSpacerItem(1, 1, QSizePolicy::Minimum, QSizePolicy::Minimum), 1, 0);
return; return;
} }
@ -73,9 +121,10 @@ EndpointWidget::EndpointWidget(uint64_t idx, EndpointHandler* eph, QWidget *pare
//tip: would need to be new widget with layout in it //tip: would need to be new widget with layout in it
//mainMuteLayout = new QGridLayout(); //mainMuteLayout = new QGridLayout();
layout->addWidget(mainLabel, 0, 0, Qt::AlignLeft | Qt::AlignBottom); layout->addWidget(mainLabel, row, 0, Qt::AlignLeft | Qt::AlignBottom);
layout->addWidget(muteButton, 0, 1, Qt::AlignLeft | Qt::AlignBottom); layout->addWidget(muteButton, row, 1, Qt::AlignLeft | Qt::AlignBottom);
layout->addWidget(mainSlider, 0, 2, 1, 2); layout->addWidget(mainSlider, row, 2, 1, 2);
row++;
//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);
@ -99,8 +148,9 @@ 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); layout->addWidget(tmp, row + 1, i);
layout->addWidget(tmpLb, 3, i); layout->addWidget(tmpLb, row + 2, 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){
@ -108,6 +158,7 @@ EndpointWidget::EndpointWidget(uint64_t idx, EndpointHandler* eph, QWidget *pare
this->channelLabels.at(i)->setText(QString::number(newValue)); this->channelLabels.at(i)->setText(QString::number(newValue));
}); });
} }
row += 3;
/* /*
* Role ExtendedCheckBoxes setup * Role ExtendedCheckBoxes setup
@ -145,11 +196,11 @@ EndpointWidget::EndpointWidget(uint64_t idx, EndpointHandler* eph, QWidget *pare
this->eph->setRoles(Roles::ROLE_COMMUNICATIONS); this->eph->setRoles(Roles::ROLE_COMMUNICATIONS);
}); });
layout->addWidget(defaultRolesCheckBoxes.at(Roles::ROLE_ALL), 5, 0); layout->addWidget(defaultRolesCheckBoxes.at(Roles::ROLE_ALL), row, 0);
layout->addWidget(defaultRolesCheckBoxes.at(Roles::ROLE_CONSOLE), 5, 1); layout->addWidget(defaultRolesCheckBoxes.at(Roles::ROLE_CONSOLE), row, 1);
layout->addWidget(defaultRolesCheckBoxes.at(Roles::ROLE_MULTIMEDIA), 5, 2); layout->addWidget(defaultRolesCheckBoxes.at(Roles::ROLE_MULTIMEDIA), row, 2);
layout->addWidget(defaultRolesCheckBoxes.at(Roles::ROLE_COMMUNICATIONS), 5, 3); layout->addWidget(defaultRolesCheckBoxes.at(Roles::ROLE_COMMUNICATIONS), row, 3);
row++;
/* ----------------------------------------------------------- */ /* ----------------------------------------------------------- */
/* /*
@ -158,6 +209,7 @@ EndpointWidget::EndpointWidget(uint64_t idx, EndpointHandler* eph, QWidget *pare
timer = new QTimer(); timer = new QTimer();
connect(timer, &QTimer::timeout, [this, eph](){ connect(timer, &QTimer::timeout, [this, eph](){
//if (memcmp(osh->callbackInfo[idx]->caller, osh->getGuid(), sizeof(NGuid)) == 0) return; CHECK IF THIS PROGRAM GENERATED THE FUNSIES IS NO LONGER IN USE FOR NOW. //if (memcmp(osh->callbackInfo[idx]->caller, osh->getGuid(), sizeof(NGuid)) == 0) return; CHECK IF THIS PROGRAM GENERATED THE FUNSIES IS NO LONGER IN USE FOR NOW.
//todo: global + constexpr + ratio
const float roundingFactor = 0.005; const float roundingFactor = 0.005;
mainSlider->blockSignals(true); mainSlider->blockSignals(true);
muteButton->blockSignals(true); muteButton->blockSignals(true);
@ -180,6 +232,14 @@ EndpointWidget::EndpointWidget(uint64_t idx, EndpointHandler* eph, QWidget *pare
}); });
timer->start(10); timer->start(10);
/* sessions */
for (size_t i = 0; i < eph->getSessionCount(); i++) {
SessionWidget* sessionWidget = new SessionWidget(i, eph->getSessionHandlers().at(i), this);
layout->addWidget(sessionWidget, row, 4);
row++;
sessionWidgets.push_back(sessionWidget);
}
//todo parent? //todo parent?
layout->addItem(new QSpacerItem(1, 1, QSizePolicy::Minimum, QSizePolicy::Minimum), 1, 0); layout->addItem(new QSpacerItem(1, 1, QSizePolicy::Minimum, QSizePolicy::Minimum), 1, 0);
layout->addItem(new QSpacerItem(1, 1, QSizePolicy::Minimum, QSizePolicy::Minimum), 4, 0); layout->addItem(new QSpacerItem(1, 1, QSizePolicy::Minimum, QSizePolicy::Minimum), 4, 0);

View file

@ -85,6 +85,25 @@ public:
}; };
class SessionWidget : public QWidget {
Q_OBJECT
public:
SessionWidget(uint64_t idx, SessionHandler* sh, QWidget *parent /* = nullptr */);
public slots:
void updateMainVolume(int newValue);
void updateMute(int checked);
private:
QLabel *mainLabel = nullptr;
QSlider *mainSlider = nullptr;
uint64_t idx;
QGridLayout *layout = nullptr;
QCheckBox *muteButton = nullptr;
SessionHandler* sh;
};
class EndpointWidget : public QWidget { class EndpointWidget : public QWidget {
Q_OBJECT Q_OBJECT
@ -126,6 +145,7 @@ private:
size_t defaultRolesVectorSize = 4; size_t defaultRolesVectorSize = 4;
QTimer* timer = nullptr; QTimer* timer = nullptr;
uint64_t idx; uint64_t idx;
std::vector<SessionWidget*> sessionWidgets;
//std::vector<EndpointHandler*> *ephs; //std::vector<EndpointHandler*> *ephs;
//std::vector<QSlider> *sliders; //std::vector<QSlider> *sliders;