AdaptiveBrightness/AdaptiveBrightness/monitor_win.cpp
2020-07-05 21:30:46 +02:00

130 lines
4.9 KiB
C++

#include "monitor.hpp"
#ifdef _MSC_VER
#include <algorithm>
#include <cmath>
#include <QtDebug>
#include <QtGlobal>
#include <highlevelmonitorconfigurationapi.h>
#include "get_last_error.hpp"
#include "log_tr.hpp"
Monitor::Monitor(HMONITOR hMonitor, PHYSICAL_MONITOR physicalMonitor)
: m_hMonitor(hMonitor)
, m_physicalMonitor(physicalMonitor.hPhysicalMonitor, physicalMonitor.szPhysicalMonitorDescription)
{
qDebug(ltr("Creating monitor '%1' with handle '0x%2' and physical handle '0x%3'")
.arg(m_physicalMonitor.name)
.arg(reinterpret_cast<qulonglong>(m_hMonitor), 0, 16)
.arg(reinterpret_cast<qulonglong>(m_physicalMonitor.handle), 0, 16));
}
Monitor::~Monitor()
{
qDebug(ltr("Destroying monitor '%1' with handle '0x%2' and physical handle '0x%3'")
.arg(m_physicalMonitor.name)
.arg(reinterpret_cast<qulonglong>(m_hMonitor), 0, 16)
.arg(reinterpret_cast<qulonglong>(m_physicalMonitor.handle), 0, 16));
}
bool Monitor::setBrightness(float percentage)
{
m_errorOccurred = true;
if(!m_brightnessRange) {
qDebug(ltr("No brightness range known for monitor '%1' with handle '0x%2' and physical handle '0x%3'")
.arg(m_physicalMonitor.name)
.arg(reinterpret_cast<qulonglong>(m_hMonitor), 0, 16)
.arg(reinterpret_cast<qulonglong>(m_physicalMonitor.handle), 0, 16));
if(std::isnan(getBrightness()))
return false;
}
const auto mappedBrightness = map(percentage, 0.f, 1.f, m_brightnessRange->first, m_brightnessRange->second);
const auto newBrightness = std::clamp<DWORD>(std::round(mappedBrightness), m_brightnessRange->first, m_brightnessRange->second);
if(!SetMonitorBrightness(m_physicalMonitor.handle, newBrightness)) {
qCritical(ltr("Failed to set brightness of monitor '%1' with handle '0x%2' and physical handle '0x%3', error: %4")
.arg(m_physicalMonitor.name)
.arg(reinterpret_cast<qulonglong>(m_hMonitor), 0, 16)
.arg(reinterpret_cast<qulonglong>(m_physicalMonitor.handle), 0, 16)
.arg(getLastErrorString()));
return false;
}
qDebug(ltr("Setting brightness of monitor '%1' with handle '0x%2' and physical handle '0x%3' to %4")
.arg(m_physicalMonitor.name)
.arg(reinterpret_cast<qulonglong>(m_hMonitor), 0, 16)
.arg(reinterpret_cast<qulonglong>(m_physicalMonitor.handle), 0, 16)
.arg(newBrightness));
m_errorOccurred = false;
return true;
}
float Monitor::getBrightness()
{
m_errorOccurred = true;
qDebug(ltr("Getting brightness of monitor '%1' with handle '0x%2' and physical handle '0x%3'")
.arg(m_physicalMonitor.name)
.arg(reinterpret_cast<qulonglong>(m_hMonitor), 0, 16)
.arg(reinterpret_cast<qulonglong>(m_physicalMonitor.handle), 0, 16));
DWORD minBrightness = 0;
DWORD brightness = 0;
DWORD maxBrightness = 0;
if(!GetMonitorBrightness(m_physicalMonitor.handle, &minBrightness, &brightness, &maxBrightness)) {
qCritical(ltr("Failed to get brightness of monitor '%1' with handle '0x%2' and physical handle '0x%3', error: %4")
.arg(m_physicalMonitor.name)
.arg(reinterpret_cast<qulonglong>(m_hMonitor), 0, 16)
.arg(reinterpret_cast<qulonglong>(m_physicalMonitor.handle), 0, 16)
.arg(getLastErrorString()));
return NAN;
}
qDebug(ltr("Got brightness %1 in range [%2, %3]").arg(brightness).arg(minBrightness).arg(maxBrightness));
m_brightnessRange = std::pair{minBrightness, maxBrightness};
m_errorOccurred = false;
return std::clamp(map(brightness, minBrightness, maxBrightness, 0.f, 1.f), 0.f, 1.f);
}
Monitor::operator bool() const
{
return !m_errorOccurred;
}
bool Monitor::hasBrightnessCapability() const
{
qDebug(ltr("Getting capabilities of monitor '%1' with handle '0x%2' and physical handle '0x%3'")
.arg(m_physicalMonitor.name)
.arg(reinterpret_cast<qulonglong>(m_hMonitor), 0, 16)
.arg(reinterpret_cast<qulonglong>(m_physicalMonitor.handle), 0, 16));
DWORD monitorCapabilities = 0;
DWORD colorTemperatures = 0;
if(!GetMonitorCapabilities(m_physicalMonitor.handle, &monitorCapabilities, &colorTemperatures)) {
qCritical(ltr("Failed to get capabilities of monitor '%1' with handle '0x%2' and physical handle '0x%3', error: %4")
.arg(m_physicalMonitor.name)
.arg(reinterpret_cast<qulonglong>(m_hMonitor), 0, 16)
.arg(reinterpret_cast<qulonglong>(m_physicalMonitor.handle), 0, 16)
.arg(getLastErrorString()));
return false;
}
return monitorCapabilities & MC_CAPS_BRIGHTNESS;
}
#endif