File indexing completed on 2024-05-12 05:38:44
0001 /* This file is part of the KDE project 0002 * SPDX-FileCopyrightText: 2017 Dorian Vogel <dorianvogel@gmail.com> 0003 * 0004 * SPDX-License-Identifier: LGPL-2.0-only 0005 * 0006 */ 0007 0008 #include "ddcutilbrightness.h" 0009 0010 #include <powerdevil_debug.h> 0011 0012 #ifdef WITH_DDCUTIL 0013 #include <ddcutil_macros.h> // for DDCUTIL_V{MAJOR,MINOR,MICRO} 0014 #define DDCUTIL_VERSION QT_VERSION_CHECK(DDCUTIL_VMAJOR, DDCUTIL_VMINOR, DDCUTIL_VMICRO) 0015 #endif 0016 0017 #include <chrono> 0018 #include <span> 0019 0020 using namespace std::chrono_literals; 0021 0022 DDCutilBrightness::DDCutilBrightness(QObject *parent) 0023 : QObject(parent) 0024 { 0025 } 0026 0027 DDCutilBrightness::~DDCutilBrightness() 0028 { 0029 } 0030 0031 void DDCutilBrightness::detect() 0032 { 0033 #ifdef WITH_DDCUTIL 0034 0035 if (qEnvironmentVariableIntValue("POWERDEVIL_NO_DDCUTIL") > 0) { 0036 return; 0037 } 0038 0039 #if DDCUTIL_VERSION >= QT_VERSION_CHECK(2, 0, 0) 0040 qCDebug(POWERDEVIL) << "Initializing ddcutil API (create ddcutil configuration file for tracing & more)..."; 0041 static DDCA_Status init_status = -1; // negative indicates error condition 0042 if (init_status < 0) { 0043 init_status = ddca_init(nullptr, DDCA_SYSLOG_NOTICE, DDCA_INIT_OPTIONS_CLIENT_OPENED_SYSLOG); 0044 } 0045 if (init_status < 0) { 0046 qCWarning(POWERDEVIL) << "Could not initialize ddcutil API. Not using DDC for monitor brightness."; 0047 return; 0048 } 0049 #endif 0050 qCDebug(POWERDEVIL) << "Check for monitors using ddca_get_display_info_list2()..."; 0051 // Inquire about detected monitors. 0052 DDCA_Display_Info_List *displays = nullptr; 0053 ddca_get_display_info_list2(false, &displays); 0054 qCInfo(POWERDEVIL) << "[DDCutilBrightness]" << displays->ct << "display(s) were detected"; 0055 0056 for (auto &displayInfo : std::span(displays->info, displays->ct)) { 0057 DDCA_Display_Handle displayHandle = nullptr; 0058 DDCA_Status rc; 0059 0060 qCDebug(POWERDEVIL) << "Opening the display reference, creating a display handle..."; 0061 if ((rc = ddca_open_display2(displayInfo.dref, true, &displayHandle))) { 0062 qCWarning(POWERDEVIL) << "[DDCutilBrightness]: ddca_open_display2" << rc; 0063 continue; 0064 } 0065 0066 auto display = std::make_unique<DDCutilDisplay>(displayInfo, displayHandle); 0067 0068 if (!display->supportsBrightness()) { 0069 qCDebug(POWERDEVIL) << "[DDCutilBrightness]: This monitor does not seem to support brightness control"; 0070 continue; 0071 } 0072 0073 qCDebug(POWERDEVIL) << "Display supports Brightness, adding handle to list"; 0074 QString displayId = generateDisplayId(displayInfo); 0075 qCDebug(POWERDEVIL) << "Create a Display Identifier:" << displayId << "for display:" << displayInfo.model_name; 0076 0077 if (displayId.isEmpty()) { 0078 qCWarning(POWERDEVIL) << "Cannot generate ID for display with model name:" << displayInfo.model_name; 0079 continue; 0080 } 0081 0082 m_displays[displayId] = std::move(display); 0083 m_displayIds += displayId; 0084 } 0085 ddca_free_display_info_list(displays); 0086 #else 0087 qCInfo(POWERDEVIL) << "[DDCutilBrightness] compiled without DDC/CI support"; 0088 return; 0089 #endif 0090 } 0091 0092 QStringList DDCutilBrightness::displayIds() const 0093 { 0094 return m_displayIds; 0095 } 0096 0097 bool DDCutilBrightness::isSupported() const 0098 { 0099 #ifdef WITH_DDCUTIL 0100 return !m_displayIds.isEmpty(); 0101 #else 0102 return false; 0103 #endif 0104 } 0105 0106 int DDCutilBrightness::brightness(const QString &displayId) 0107 { 0108 if (!m_displayIds.contains(displayId)) { 0109 return -1; 0110 } 0111 0112 return m_displays[displayId]->brightness(); 0113 } 0114 0115 int DDCutilBrightness::maxBrightness(const QString &displayId) 0116 { 0117 if (!m_displayIds.contains(displayId)) { 0118 return -1; 0119 } 0120 0121 return m_displays[displayId]->maxBrightness(); 0122 } 0123 0124 void DDCutilBrightness::setBrightness(const QString &displayId, int value) 0125 { 0126 if (!m_displayIds.contains(displayId)) { 0127 return; 0128 } 0129 0130 qCDebug(POWERDEVIL) << "setBrightness: displayId:" << displayId << "brightness:" << value; 0131 m_displays[displayId]->setBrightness(value); 0132 } 0133 0134 #ifdef WITH_DDCUTIL 0135 QString DDCutilBrightness::generateDisplayId(const DDCA_Display_Info &displayInfo) const 0136 { 0137 switch (displayInfo.path.io_mode) { 0138 case DDCA_IO_I2C: 0139 return QString("i2c:%1").arg(displayInfo.path.path.i2c_busno); 0140 case DDCA_IO_USB: 0141 return QString("usb:%1").arg(displayInfo.path.path.hiddev_devno); 0142 } 0143 return QString(); 0144 } 0145 #endif 0146 0147 #include "moc_ddcutilbrightness.cpp"