re-add sys-clk manager, default to mtc auto adj (others are useless), new gpu table for erista units, custom sys-clk updates
338 lines
11 KiB
C++
338 lines
11 KiB
C++
/*
|
|
sys-clk manager, a sys-clk frontend homebrew
|
|
Copyright (C) 2019 natinusala
|
|
Copyright (C) 2019 p-sam
|
|
Copyright (C) 2019 m4xw
|
|
|
|
This program is free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include "status_tab.h"
|
|
|
|
#include "ipc/client.h"
|
|
|
|
#include "utils.h"
|
|
|
|
#define DANGEROUS_TEMP_THRESHOLD 84000
|
|
#define DANGEROUS_TEMP_COLOR nvgRGB(255, 85, 0)
|
|
|
|
StatusTab::StatusTab(RefreshTask *refreshTask) :
|
|
brls::List(),
|
|
refreshTask(refreshTask)
|
|
{
|
|
// Get context
|
|
SysClkContext context;
|
|
Result rc = sysclkIpcGetCurrentContext(&context);
|
|
|
|
if (R_FAILED(rc))
|
|
{
|
|
brls::Logger::error("Unable to get context");
|
|
errorResult("sysclkIpcGetCurrentContext", rc);
|
|
brls::Application::crash("Could not get the current sys-clk context, please check that it is correctly installed and enabled.");
|
|
return;
|
|
}
|
|
|
|
// Customize list
|
|
this->setSpacing(10);
|
|
this->setMarginBottom(0);
|
|
|
|
// Enabled option
|
|
brls::ToggleListItem *serviceEnabledListItem = new brls::ToggleListItem("Enable service", context.enabled, "", "Yes", "No");
|
|
|
|
serviceEnabledListItem->getClickEvent()->subscribe([this, serviceEnabledListItem](View* view)
|
|
{
|
|
bool enabled = serviceEnabledListItem->getToggleState();
|
|
brls::Logger::info("New service state = %d", enabled);
|
|
|
|
Result rc = sysclkIpcSetEnabled(enabled);
|
|
|
|
if (R_FAILED(rc))
|
|
{
|
|
brls::Logger::error("Unable to set enabled state");
|
|
errorResult("sysclkIpcSetEnabled", rc);
|
|
// TODO: Put it back to on / off
|
|
}
|
|
|
|
this->refreshTask->fireNow();
|
|
});
|
|
|
|
this->addView(serviceEnabledListItem);
|
|
|
|
// Frequencies
|
|
brls::Header *freqsHeader = new brls::Header("Frequencies");
|
|
this->addView(freqsHeader);
|
|
|
|
brls::BoxLayout *freqsBox = new brls::BoxLayout(brls::BoxLayoutOrientation::VERTICAL);
|
|
freqsBox->setSpacing(0);
|
|
freqsBox->setHeight(60);
|
|
this->addView(freqsBox);
|
|
|
|
StatusGrid *freqsLayout = new StatusGrid();
|
|
freqsLayout->setSpacing(22);
|
|
freqsLayout->setHeight(40);
|
|
|
|
this->cpuFreqCell = new StatusCell("CPU", formatFreq(context.freqs[SysClkModule_CPU]));
|
|
this->gpuFreqCell = new StatusCell("GPU", formatFreq(context.freqs[SysClkModule_GPU]));
|
|
this->memFreqCell = new StatusCell("MEM", formatFreq(context.freqs[SysClkModule_MEM]));
|
|
|
|
freqsLayout->addView(this->cpuFreqCell);
|
|
freqsLayout->addView(this->gpuFreqCell);
|
|
freqsLayout->addView(this->memFreqCell);
|
|
|
|
freqsBox->addView(freqsLayout);
|
|
|
|
StatusGrid *realFreqsLayout = new StatusGrid();
|
|
realFreqsLayout->setSpacing(22);
|
|
realFreqsLayout->setHeight(24);
|
|
|
|
this->realCpuFreqCell = new StatusCell("\uE090", formatFreq(context.realFreqs[SysClkModule_CPU]));
|
|
this->realGpuFreqCell = new StatusCell("\uE090", formatFreq(context.realFreqs[SysClkModule_GPU]));
|
|
this->realMemFreqCell = new StatusCell("\uE090", formatFreq(context.realFreqs[SysClkModule_MEM]));
|
|
|
|
realFreqsLayout->addView(this->realCpuFreqCell);
|
|
realFreqsLayout->addView(this->realGpuFreqCell);
|
|
realFreqsLayout->addView(this->realMemFreqCell);
|
|
|
|
freqsBox->addView(realFreqsLayout);
|
|
|
|
// Temperatures
|
|
brls::Header *temperaturesHeader = new brls::Header("Temperatures");
|
|
this->addView(temperaturesHeader);
|
|
StatusGrid *tempsLayout = new StatusGrid();
|
|
tempsLayout->setSpacing(22);
|
|
tempsLayout->setHeight(40);
|
|
|
|
this->skinTempCell = new StatusCell("Skin", formatTemp(context.temps[SysClkThermalSensor_Skin]));
|
|
this->socTempCell = new StatusCell("SOC", formatTemp(context.temps[SysClkThermalSensor_SOC]));
|
|
this->pcbTempCell = new StatusCell("PCB", formatTemp(context.temps[SysClkThermalSensor_PCB]));
|
|
|
|
if (context.temps[SysClkThermalSensor_SOC] > DANGEROUS_TEMP_THRESHOLD)
|
|
this->socTempCell->setValueColor(DANGEROUS_TEMP_COLOR);
|
|
|
|
if (context.temps[SysClkThermalSensor_PCB] > DANGEROUS_TEMP_THRESHOLD)
|
|
this->pcbTempCell->setValueColor(DANGEROUS_TEMP_COLOR);
|
|
|
|
if (context.temps[SysClkThermalSensor_Skin] > DANGEROUS_TEMP_THRESHOLD)
|
|
this->skinTempCell->setValueColor(DANGEROUS_TEMP_COLOR);
|
|
|
|
tempsLayout->addView(this->socTempCell);
|
|
tempsLayout->addView(this->pcbTempCell);
|
|
tempsLayout->addView(this->skinTempCell);
|
|
|
|
this->addView(tempsLayout);
|
|
|
|
// Power
|
|
brls::Header *powerHeader = new brls::Header("Power");
|
|
this->addView(powerHeader);
|
|
StatusGrid *powerLayout = new StatusGrid();
|
|
powerLayout->setSpacing(22);
|
|
powerLayout->setHeight(40);
|
|
|
|
this->nowPowerCell = new StatusCell("Now", formatPower(context.power[SysClkPowerSensor_Now]));
|
|
this->avgPowerCell = new StatusCell("Avg", formatPower(context.power[SysClkPowerSensor_Avg]));
|
|
|
|
powerLayout->addView(new StatusCell("", ""));
|
|
powerLayout->addView(this->nowPowerCell);
|
|
powerLayout->addView(this->avgPowerCell);
|
|
|
|
this->addView(powerLayout);
|
|
|
|
// Info
|
|
brls::Header *systemHeader = new brls::Header("System");
|
|
this->addView(systemHeader);
|
|
|
|
InfoGrid *infoLayout = new InfoGrid();
|
|
infoLayout->setSpacing(22);
|
|
infoLayout->setHeight(40);
|
|
|
|
this->profileCell = new StatusCell("Profile", formatProfile(context.profile));
|
|
this->tidCell = new StatusCell("Application ID", formatTid(context.applicationId));
|
|
|
|
infoLayout->addView(this->profileCell);
|
|
infoLayout->addView(this->tidCell);
|
|
|
|
this->addView(infoLayout);
|
|
|
|
// Setup refresh task
|
|
this->freqListenerSub = refreshTask->registerFreqListener([this](SysClkModule module, uint32_t freq) {
|
|
switch(module)
|
|
{
|
|
case SysClkModule_CPU:
|
|
this->cpuFreqCell->setValue(formatFreq(freq));
|
|
break;
|
|
case SysClkModule_GPU:
|
|
this->gpuFreqCell->setValue(formatFreq(freq));
|
|
break;
|
|
case SysClkModule_MEM:
|
|
this->memFreqCell->setValue(formatFreq(freq));
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
});
|
|
|
|
this->realFreqListenerSub = refreshTask->registerFreqListener([this](SysClkModule module, uint32_t freq) {
|
|
switch(module)
|
|
{
|
|
case SysClkModule_CPU:
|
|
this->realCpuFreqCell->setValue(formatFreq(freq));
|
|
break;
|
|
case SysClkModule_GPU:
|
|
this->realGpuFreqCell->setValue(formatFreq(freq));
|
|
break;
|
|
case SysClkModule_MEM:
|
|
this->realMemFreqCell->setValue(formatFreq(freq));
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
});
|
|
|
|
this->appIdListenerSub = refreshTask->registerAppIdListener([this](uint64_t tid) {
|
|
this->tidCell->setValue(formatTid(tid));
|
|
});
|
|
|
|
this->profileListenerSub = refreshTask->registerProfileListener([this](SysClkProfile profile) {
|
|
this->profileCell->setValue(formatProfile(profile));
|
|
});
|
|
|
|
this->tempListenerSub = refreshTask->registerTempListener([this](SysClkThermalSensor sensor, uint32_t temp) {
|
|
switch (sensor)
|
|
{
|
|
case SysClkThermalSensor_PCB:
|
|
this->pcbTempCell->setValue(formatTemp(temp));
|
|
|
|
if (temp > DANGEROUS_TEMP_THRESHOLD)
|
|
this->pcbTempCell->setValueColor(DANGEROUS_TEMP_COLOR);
|
|
else
|
|
this->pcbTempCell->resetValueColor();
|
|
break;
|
|
case SysClkThermalSensor_SOC:
|
|
this->socTempCell->setValue(formatTemp(temp));
|
|
|
|
if (temp > DANGEROUS_TEMP_THRESHOLD)
|
|
this->socTempCell->setValueColor(DANGEROUS_TEMP_COLOR);
|
|
else
|
|
this->socTempCell->resetValueColor();
|
|
|
|
break;
|
|
case SysClkThermalSensor_Skin:
|
|
this->skinTempCell->setValue(formatTemp(temp));
|
|
|
|
if (temp > DANGEROUS_TEMP_THRESHOLD)
|
|
this->skinTempCell->setValueColor(DANGEROUS_TEMP_COLOR);
|
|
else
|
|
this->skinTempCell->resetValueColor();
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
});
|
|
}
|
|
|
|
StatusTab::~StatusTab()
|
|
{
|
|
refreshTask->unregisterFreqListener(this->freqListenerSub);
|
|
refreshTask->unregisterRealFreqListener(this->realFreqListenerSub);
|
|
refreshTask->unregisterAppIdListener(this->appIdListenerSub);
|
|
refreshTask->unregisterProfileListener(this->profileListenerSub);
|
|
refreshTask->unregisterTempListener(this->tempListenerSub);
|
|
}
|
|
|
|
StatusGrid::StatusGrid()
|
|
: BoxLayout(brls::BoxLayoutOrientation::HORIZONTAL)
|
|
{
|
|
|
|
}
|
|
|
|
void StatusGrid::layout(NVGcontext* vg, brls::Style *style, brls::FontStash *stash)
|
|
{
|
|
// Distribute space equally between children
|
|
if (!this->children.empty())
|
|
{
|
|
size_t size = this->children.size();
|
|
unsigned width = (this->getWidth()- this->marginLeft - this->marginRight - this->getSpacing() * (size - 1)) / size;
|
|
|
|
for (brls::BoxLayoutChild *child : this->children)
|
|
{
|
|
if (!child->fill)
|
|
child->view->setWidth(width);
|
|
}
|
|
}
|
|
|
|
// Layout normally
|
|
BoxLayout::layout(vg, style, stash);
|
|
}
|
|
|
|
InfoGrid::InfoGrid() : BoxLayout(brls::BoxLayoutOrientation::HORIZONTAL)
|
|
{
|
|
|
|
}
|
|
|
|
void InfoGrid::layout(NVGcontext* vg, brls::Style *style, brls::FontStash *stash)
|
|
{
|
|
// Give first child one third of the view, give second child the rest
|
|
if (this->children.size() >= 2)
|
|
{
|
|
size_t size = 3;
|
|
unsigned firstWidth = (this->getWidth()- this->marginLeft - this->marginRight - this->getSpacing() * (size - 1)) / size;
|
|
unsigned secondWidth = firstWidth * 2 + this->getSpacing();
|
|
|
|
this->children[0]->view->setWidth(firstWidth);
|
|
this->children[1]->view->setWidth(secondWidth);
|
|
}
|
|
|
|
// Layout normally
|
|
BoxLayout::layout(vg, style, stash);
|
|
}
|
|
|
|
StatusCell::StatusCell(std::string label, std::string value) : label(label), value(value)
|
|
{
|
|
this->resetValueColor();
|
|
}
|
|
|
|
void StatusCell::setValue(std::string value)
|
|
{
|
|
this->value = value;
|
|
}
|
|
|
|
void StatusCell::draw(NVGcontext *vg, int x, int y, unsigned width, unsigned height, brls::Style *style, brls::FrameContext *ctx)
|
|
{
|
|
unsigned padding = 5;
|
|
|
|
// Label
|
|
nvgBeginPath(vg);
|
|
nvgFillColor(vg, a(ctx->theme->tableBodyTextColor));
|
|
nvgFontSize(vg, 16);
|
|
nvgTextAlign(vg, NVG_ALIGN_LEFT | NVG_ALIGN_BASELINE);
|
|
nvgText(vg, x + padding, y + height / 2, this->label.c_str(), nullptr);
|
|
|
|
// Value
|
|
nvgBeginPath(vg);
|
|
nvgFillColor(vg, a(this->valueColor));
|
|
nvgFontSize(vg, 20);
|
|
nvgTextAlign(vg, NVG_ALIGN_RIGHT | NVG_ALIGN_BASELINE);
|
|
nvgText(vg, x + width - padding, y + height / 2, this->value.c_str(), nullptr);
|
|
}
|
|
|
|
void StatusCell::setValueColor(NVGcolor color)
|
|
{
|
|
this->valueColor = color;
|
|
}
|
|
|
|
void StatusCell::resetValueColor()
|
|
{
|
|
this->valueColor = brls::Application::getThemeValues()->textColor;
|
|
}
|