Brightness (Linux): allow specifying busno for ddcutil

Ref: #580
This commit is contained in:
李通洲
2023-10-14 01:38:02 +08:00
parent 839ff311de
commit 42e87b498c
3 changed files with 97 additions and 26 deletions
+69 -26
View File
@@ -92,18 +92,80 @@ static const char* detectWithBacklight(FFlist* result)
#include <ddcutil_c_api.h>
typedef struct DdcutilData
{
FF_LIBRARY_SYMBOL(ddca_open_display2)
FF_LIBRARY_SYMBOL(ddca_get_any_vcp_value_using_explicit_type)
FF_LIBRARY_SYMBOL(ddca_free_any_vcp_value)
FF_LIBRARY_SYMBOL(ddca_close_display)
} DdcutilData;
static void detectWithDdcciImpl(DdcutilData* data, FFlist* result, DDCA_Display_Info* dinfo)
{
DDCA_Display_Handle handle;
if (data->ffddca_open_display2(dinfo->dref, false, &handle) >= 0)
{
DDCA_Any_Vcp_Value* vcpValue = NULL;
if (data->ffddca_get_any_vcp_value_using_explicit_type(handle, 0x10 /*brightness*/, DDCA_NON_TABLE_VCP_VALUE, &vcpValue) >= 0)
{
assert(vcpValue->value_type == DDCA_NON_TABLE_VCP_VALUE);
int current = VALREC_CUR_VAL(vcpValue), max = VALREC_MAX_VAL(vcpValue);
data->ffddca_free_any_vcp_value(vcpValue);
FFBrightnessResult* brightness = (FFBrightnessResult*) ffListAdd(result);
brightness->max = max;
brightness->min = 0;
brightness->current = current;
ffStrbufInitS(&brightness->name, dinfo->model_name);
}
data->ffddca_close_display(handle);
}
}
static const char* detectWithDdcci(FFlist* result)
{
FF_LIBRARY_LOAD(libddcutil, &instance.config.libDdcutil, "dlopen ddcutil failed", "libddcutil" FF_LIBRARY_EXTENSION, 5);
FF_LIBRARY_LOAD(libddcutil, &instance.config.libDdcutil, "dlopen ddcutil failed", "libddcutil" FF_LIBRARY_EXTENSION, 5)
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libddcutil, ddca_get_display_info_list2)
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libddcutil, ddca_open_display2)
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libddcutil, ddca_get_any_vcp_value_using_explicit_type)
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libddcutil, ddca_free_any_vcp_value)
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libddcutil, ddca_close_display)
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libddcutil, ddca_get_display_info)
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libddcutil, ddca_create_busno_display_identifier)
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libddcutil, ddca_create_display_ref)
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libddcutil, ddca_free_display_identifier)
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libddcutil, ddca_free_display_ref)
DdcutilData ddcutilData;
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libddcutil, ddcutilData, ddca_open_display2)
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libddcutil, ddcutilData, ddca_get_any_vcp_value_using_explicit_type)
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libddcutil, ddcutilData, ddca_free_any_vcp_value)
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libddcutil, ddcutilData, ddca_close_display)
libddcutil = NULL; // Don't dlclose libddcutil. See https://github.com/rockowitz/ddcutil/issues/330
if (instance.config.brightness.busNos.length)
{
FF_SUPPRESS_IO();
FF_LIST_FOR_EACH(int, busno, instance.config.brightness.busNos)
{
DDCA_Display_Identifier did;
if (ffddca_create_busno_display_identifier(*busno, &did) >= 0)
{
DDCA_Display_Ref dref;
if (ffddca_create_display_ref(did, &dref) >= 0)
{
FF_AUTO_FREE DDCA_Display_Info* dinfo = NULL;
if (ffddca_get_display_info(dref, &dinfo) >= 0)
detectWithDdcciImpl(&ddcutilData, result, dinfo);
ffddca_free_display_ref(dref);
}
ffddca_free_display_identifier(did);
}
}
return NULL;
}
FF_AUTO_FREE DDCA_Display_Info_List* infoList = NULL;
if (__builtin_expect(ffddca_get_display_info_list2(false, &infoList) < 0, 0))
if (ffddca_get_display_info_list2(false, &infoList) < 0)
return "ddca_get_display_info_list2(false, &infoList) failed";
if (infoList->ct == 0)
@@ -111,26 +173,7 @@ static const char* detectWithDdcci(FFlist* result)
for (int index = 0; index < infoList->ct; ++index)
{
const DDCA_Display_Info* display = &infoList->info[index];
DDCA_Display_Handle handle;
if (ffddca_open_display2(display->dref, false, &handle) >= 0)
{
DDCA_Any_Vcp_Value* vcpValue = NULL;
if (ffddca_get_any_vcp_value_using_explicit_type(handle, 0x10 /*brightness*/, DDCA_NON_TABLE_VCP_VALUE, &vcpValue) >= 0)
{
assert(vcpValue->value_type == DDCA_NON_TABLE_VCP_VALUE);
int current = VALREC_CUR_VAL(vcpValue), max = VALREC_MAX_VAL(vcpValue);
ffddca_free_any_vcp_value(vcpValue);
FFBrightnessResult* brightness = (FFBrightnessResult*) ffListAdd(result);
brightness->max = max;
brightness->min = 0;
brightness->current = current;
ffStrbufInitS(&brightness->name, display->model_name);
}
ffddca_close_display(handle);
}
detectWithDdcciImpl(&ddcutilData, result, &infoList->info[index]);
}
return NULL;
+24
View File
@@ -88,6 +88,10 @@ void ffInitBrightnessOptions(FFBrightnessOptions* options)
{
ffOptionInitModuleBaseInfo(&options->moduleInfo, FF_BRIGHTNESS_MODULE_NAME, ffParseBrightnessCommandOptions, ffParseBrightnessJsonObject, ffPrintBrightness, ffGenerateBrightnessJson, ffPrintBrightnessHelpFormat);
ffOptionInitModuleArg(&options->moduleArgs);
#ifdef __linux__
ffListInit(&options->busNos, sizeof(int));
#endif
}
bool ffParseBrightnessCommandOptions(FFBrightnessOptions* options, const char* key, const char* value)
@@ -103,6 +107,10 @@ bool ffParseBrightnessCommandOptions(FFBrightnessOptions* options, const char* k
void ffDestroyBrightnessOptions(FFBrightnessOptions* options)
{
ffOptionDestroyModuleArg(&options->moduleArgs);
#ifdef __linux__
ffListDestroy(&options->busNos);
#endif
}
void ffParseBrightnessJsonObject(FFBrightnessOptions* options, yyjson_val* module)
@@ -118,6 +126,22 @@ void ffParseBrightnessJsonObject(FFBrightnessOptions* options, yyjson_val* modul
if (ffJsonConfigParseModuleArgs(key, val, &options->moduleArgs))
continue;
#ifdef __linux__
if(ffStrEqualsIgnCase(key, "busNos"))
{
if (!yyjson_is_arr(val)) continue;
yyjson_val* item;
size_t idx, max;
yyjson_arr_foreach(val, idx, max, item)
{
if (!yyjson_is_int(item)) continue;
*(int*) ffListAdd(&options->busNos) = yyjson_get_int(item);
}
continue;
}
#endif
ffPrintError(FF_BRIGHTNESS_MODULE_NAME, 0, &options->moduleArgs, "Unknown JSON key %s", key);
}
}
+4
View File
@@ -8,4 +8,8 @@ typedef struct FFBrightnessOptions
{
FFModuleBaseInfo moduleInfo;
FFModuleArgs moduleArgs;
#ifdef __linux__
FFlist busNos;
#endif
} FFBrightnessOptions;