diff --git a/CMakeLists.txt b/CMakeLists.txt --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -50,16 +50,17 @@ find_package(XCB REQUIRED COMPONENTS XCB RANDR DPMS) -option(WITH_DDCUTIL "DDCUtil library support" OFF) -if(WITH_DDCUTIL) - find_package(DDCUtil REQUIRED) - set_package_properties(DDCUtil - PROPERTIES DESCRIPTION "DDCUtil library support" - TYPE OPTIONAL - PURPOSE "Set monitor settings over DDC/CI channel" - ) +option(HAVE_DDCUTIL "DDCUtil library support" OFF) +if(HAVE_DDCUTIL) + find_package(DDCUtil REQUIRED) + add_compile_definitions(WITH_DDCUTIL) + set_package_properties(DDCUtil + PROPERTIES DESCRIPTION "DDCUtil library support" + TYPE OPTIONAL + PURPOSE "Set monitor settings over DDC/CI channel" + ) else() - add_feature_info("DDCUtil" "Off" "DDCUtil library support is disabled by default as recomemded by authors, add -DWITH_DDCUTIL=On to enable") + add_feature_info("DDCUtil" HAVE_DDCUTIL "DDCUtil library support is disabled by default as recomended by authors, add -DHAVE_DDCUTIL=On to enable") endif() include_directories ( @@ -73,6 +74,8 @@ add_subdirectory(kcmodule) add_subdirectory(doc) + + install( FILES powerdevil.notifyrc DESTINATION ${KDE_INSTALL_KNOTIFY5RCDIR} ) feature_summary(WHAT ALL INCLUDE_QUIET_PACKAGES FATAL_ON_MISSING_REQUIRED_PACKAGES) diff --git a/daemon/backends/upower/ddcutilbrightness.h b/daemon/backends/upower/ddcutilbrightness.h --- a/daemon/backends/upower/ddcutilbrightness.h +++ b/daemon/backends/upower/ddcutilbrightness.h @@ -49,9 +49,8 @@ #endif //ifdef WITH_DDCUTIL //Per display properties //destription mapped to vcp values for easy retrieval - QVector > m_descrToVcp_perDisp; - QVector > > m_vcpTovcpValueWithDescr_perDisp; - + QVector m_usedVcp; + QVector> m_supportedVcp_perDisp; long m_tmpCurrentBrightness; QTimer m_setBrightnessEventFilter; diff --git a/daemon/backends/upower/ddcutilbrightness.cpp b/daemon/backends/upower/ddcutilbrightness.cpp --- a/daemon/backends/upower/ddcutilbrightness.cpp +++ b/daemon/backends/upower/ddcutilbrightness.cpp @@ -20,8 +20,8 @@ #include #include "ddcutilbrightness.h" - DDCutilBrightness::DDCutilBrightness() + : m_usedVcp({0x10}) { m_setBrightnessEventFilter.setInterval(100); m_setBrightnessEventFilter.setSingleShot(true); @@ -30,21 +30,16 @@ void DDCutilBrightness::detect() { -#ifndef WITH_DDCUTIL - qCInfo(POWERDEVIL) << "[DDCutilBrightness] compiled without DDC/CI support"; - return; -#else +#ifdef WITH_DDCUTIL DDCA_Status rc; qCDebug(POWERDEVIL) << "Check for monitors using ddca_get_displays()..."; // Inquire about detected monitors. - DDCA_Display_Info_List * dlist = ddca_get_display_info_list(); - qCDebug(POWERDEVIL) << "ddca_get_display_info_list() returned "<< dlist; + DDCA_Display_Info_List * dlist = NULL; + ddca_get_display_info_list2(true, &dlist); qCInfo(POWERDEVIL) << "[DDCutilBrightness] " << dlist->ct << "display(s) were detected"; - for (int iDisp=0;iDispct;iDisp++) { - DDCA_Display_Identifier did; - DDCA_Display_Ref dref; + for (int iDisp = 0; iDisp < dlist->ct; ++iDisp) { DDCA_Display_Handle dh = nullptr; // initialize to avoid clang analyzer warning qCDebug(POWERDEVIL) << "Create a Display Identifier for display"<info[iDisp]); - rc = ddca_create_dispno_display_identifier(iDisp+1, &did); // ddcutil uses 1 paded indexing for displays - - char * did_repr = ddca_did_repr(did); - - qCDebug(POWERDEVIL) << "did="<info[iDisp].dref, true, &dh); if (rc != 0) { qCWarning(POWERDEVIL) << "[DDCutilBrightness]: ddct_open_display"<< rc; continue; } - - qCDebug(POWERDEVIL) << "adding handle to list"; - m_displayHandleList.append(dh); - qCDebug(POWERDEVIL) << "handles nb: "<vcp_code_ct << "capabilities parsed"; - - - m_descrToVcp_perDisp.append(QMap()); - m_vcpTovcpValueWithDescr_perDisp.append(QMap >() ); - //fill the feature description to vcp LUT - - DDCA_Version_Feature_Info* featureInfo; - for (int iVcp=0;iVcpvcp_code_ct;iVcp++) { - - int vcpCode=parsedCapabilities->vcp_codes[iVcp].feature_code; - - m_vcpTovcpValueWithDescr_perDisp[iDisp].insert(vcpCode, QMap()); - - m_descrToVcp_perDisp[iDisp].insert( - QString(ddca_get_feature_name(vcpCode)), vcpCode); - - - ddca_get_feature_info_by_display(m_displayHandleList.at(iDisp), vcpCode, &featureInfo); - if (featureInfo == nullptr) { - continue; + + DDCA_Feature_List vcpList; + ddca_get_feature_list_by_dref(DDCA_SUBSET_COLOR, dh, false, &vcpList); + qCDebug(POWERDEVIL) << "ddca_feature_list: "<< ddca_feature_list_string(&vcpList, "0x", ","); + QVector tmpVcpList; + for (int iVcp = 0; iVcp < m_usedVcp.count(); ++iVcp) { + if (ddca_feature_list_contains(&vcpList, m_usedVcp.value(iVcp))) { + tmpVcpList.append(m_usedVcp.value(iVcp)); + } - qCDebug(POWERDEVIL) << featureInfo->feature_code<<":"<desc; - if ((featureInfo->feature_flags & DDCA_SIMPLE_NC) != DDCA_SIMPLE_NC) { - continue; - } - for (int iVcpVal=0;featureInfo->sl_values[iVcpVal].value_code!=0;++iVcpVal) { - - qCDebug(POWERDEVIL) << "\t"<sl_values[iVcpVal].value_code - <<":"<< featureInfo->sl_values[iVcpVal].value_name; - - bool thisVcpValIsSupported=false; - - for (int iSupportedVcpVal=0; iSupportedVcpValvcp_codes[iVcp].value_ct; iSupportedVcpVal++) { - if(parsedCapabilities->vcp_codes[iVcp].values[iSupportedVcpVal] - ==featureInfo->sl_values[iVcpVal].value_code) { - thisVcpValIsSupported=true; - } - } - - if (thisVcpValIsSupported) { - (m_vcpTovcpValueWithDescr_perDisp[iDisp])[vcpCode].insert( - featureInfo->sl_values[iVcpVal].value_code, - featureInfo->sl_values[iVcpVal].value_name); - } + else { + qCDebug(POWERDEVIL) << "[DDCutilBrightness]: This monitor does not seem to support " << m_usedVcp[iVcp]; } } - ddca_free_display_identifier(did); - ddca_free_parsed_capabilities(parsedCapabilities); + + + //we only store displays that actually support the features we want. + if( tmpVcpList.contains(0x10) ) { + qCDebug(POWERDEVIL) << "Display supports Brightness, adding handle to list"; + m_displayHandleList.append(dh); + m_supportedVcp_perDisp.value(iDisp).append(tmpVcpList); + } } +#else + qCInfo(POWERDEVIL) << "[DDCutilBrightness] compiled without DDC/CI support"; + return; #endif } bool DDCutilBrightness::isSupported() const { -#ifndef WITH_DDCUTIL - return false; -#else +#ifdef WITH_DDCUTIL return !m_displayHandleList.isEmpty(); +#else + return false; #endif } @@ -153,22 +97,20 @@ { #ifdef WITH_DDCUTIL //we check whether the timer is running, this means we received new values but did not send them yet to the monitor - //not checking that results in the brightness slider jump to the previous vqlue when changing. - if(m_setBrightnessEventFilter.isActive()) { + //not checking that results in the brightness slider jump to the previous value when changing. + if (m_setBrightnessEventFilter.isActive()) { m_lastBrightnessKnown = m_tmpCurrentBrightness; - } - else { //FIXME: gets value for display 1 + } else { //FIXME: gets value for display 1 DDCA_Status rc; - DDCA_Single_Vcp_Value *returnValue; + DDCA_Non_Table_Vcp_Value returnValue; - rc = ddca_get_vcp_value(m_displayHandleList.at(0), - m_descrToVcp_perDisp.at(0).value("Brightness"), - DDCA_NON_TABLE_VCP_VALUE, &returnValue); + rc = ddca_get_non_table_vcp_value(m_displayHandleList.at(0), + 0x10, &returnValue); qCDebug(POWERDEVIL) << "[DDCutilBrightness::brightness]: ddca_get_vcp_value returned" << rc; //check rc to prevent crash on wake from idle and the monitor has gone to powersave mode if (rc == 0) { - m_lastBrightnessKnown = (long)returnValue->val.c.cur_val; + m_lastBrightnessKnown = (long)(returnValue.sh <<8|returnValue.sl); } } return m_lastBrightnessKnown; @@ -181,16 +123,15 @@ { #ifdef WITH_DDCUTIL DDCA_Status rc; - DDCA_Single_Vcp_Value *returnValue; + DDCA_Non_Table_Vcp_Value returnValue; - rc = ddca_get_vcp_value(m_displayHandleList.at(0), - m_descrToVcp_perDisp.at(0).value("Brightness"), - DDCA_NON_TABLE_VCP_VALUE, &returnValue); + rc = ddca_get_non_table_vcp_value(m_displayHandleList.at(0) + , 0x10, &returnValue); qCDebug(POWERDEVIL) << "[DDCutilBrightness::brightnessMax]: ddca_get_vcp_value returned" << rc; //check rc to prevent crash on wake from idle and the monitor has gone to powersave mode if (rc == 0) { - m_lastMaxBrightnessKnown = (long)returnValue->val.c.max_val; + m_lastMaxBrightnessKnown = (long)(returnValue.mh <<8|returnValue.ml); } return m_lastMaxBrightnessKnown; @@ -210,13 +151,14 @@ { #ifdef WITH_DDCUTIL DDCA_Status rc; - for (int iDisp=0;iDisp> 8; + uint8_t newsl = (uint16_t)m_tmpCurrentBrightness & 0x00ff; + rc = ddca_set_non_table_vcp_value(m_displayHandleList.at(iDisp), 0x10, + newsh, newsl); - if (rc != 0) { + if (rc < 0) { qCWarning(POWERDEVIL) << "[DDCutilBrightness::setBrightness] failed, trying to detect()"; detect(); } else {