Skip to content

Commit 42e87b4

Browse files
committed
Brightness (Linux): allow specifying busno for ddcutil
Ref: #580
1 parent 839ff31 commit 42e87b4

File tree

3 files changed

+97
-26
lines changed

3 files changed

+97
-26
lines changed

src/detection/brightness/brightness_linux.c

Lines changed: 69 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -92,45 +92,88 @@ static const char* detectWithBacklight(FFlist* result)
9292

9393
#include <ddcutil_c_api.h>
9494

95+
typedef struct DdcutilData
96+
{
97+
FF_LIBRARY_SYMBOL(ddca_open_display2)
98+
FF_LIBRARY_SYMBOL(ddca_get_any_vcp_value_using_explicit_type)
99+
FF_LIBRARY_SYMBOL(ddca_free_any_vcp_value)
100+
FF_LIBRARY_SYMBOL(ddca_close_display)
101+
} DdcutilData;
102+
103+
static void detectWithDdcciImpl(DdcutilData* data, FFlist* result, DDCA_Display_Info* dinfo)
104+
{
105+
DDCA_Display_Handle handle;
106+
if (data->ffddca_open_display2(dinfo->dref, false, &handle) >= 0)
107+
{
108+
DDCA_Any_Vcp_Value* vcpValue = NULL;
109+
if (data->ffddca_get_any_vcp_value_using_explicit_type(handle, 0x10 /*brightness*/, DDCA_NON_TABLE_VCP_VALUE, &vcpValue) >= 0)
110+
{
111+
assert(vcpValue->value_type == DDCA_NON_TABLE_VCP_VALUE);
112+
int current = VALREC_CUR_VAL(vcpValue), max = VALREC_MAX_VAL(vcpValue);
113+
data->ffddca_free_any_vcp_value(vcpValue);
114+
115+
FFBrightnessResult* brightness = (FFBrightnessResult*) ffListAdd(result);
116+
brightness->max = max;
117+
brightness->min = 0;
118+
brightness->current = current;
119+
ffStrbufInitS(&brightness->name, dinfo->model_name);
120+
}
121+
data->ffddca_close_display(handle);
122+
}
123+
}
124+
95125
static const char* detectWithDdcci(FFlist* result)
96126
{
97-
FF_LIBRARY_LOAD(libddcutil, &instance.config.libDdcutil, "dlopen ddcutil failed", "libddcutil" FF_LIBRARY_EXTENSION, 5);
127+
FF_LIBRARY_LOAD(libddcutil, &instance.config.libDdcutil, "dlopen ddcutil failed", "libddcutil" FF_LIBRARY_EXTENSION, 5)
98128
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libddcutil, ddca_get_display_info_list2)
99-
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libddcutil, ddca_open_display2)
100-
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libddcutil, ddca_get_any_vcp_value_using_explicit_type)
101-
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libddcutil, ddca_free_any_vcp_value)
102-
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libddcutil, ddca_close_display)
129+
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libddcutil, ddca_get_display_info)
130+
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libddcutil, ddca_create_busno_display_identifier)
131+
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libddcutil, ddca_create_display_ref)
132+
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libddcutil, ddca_free_display_identifier)
133+
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libddcutil, ddca_free_display_ref)
134+
135+
DdcutilData ddcutilData;
136+
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libddcutil, ddcutilData, ddca_open_display2)
137+
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libddcutil, ddcutilData, ddca_get_any_vcp_value_using_explicit_type)
138+
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libddcutil, ddcutilData, ddca_free_any_vcp_value)
139+
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libddcutil, ddcutilData, ddca_close_display)
103140
libddcutil = NULL; // Don't dlclose libddcutil. See https://github.com/rockowitz/ddcutil/issues/330
104141

142+
if (instance.config.brightness.busNos.length)
143+
{
144+
FF_SUPPRESS_IO();
145+
146+
FF_LIST_FOR_EACH(int, busno, instance.config.brightness.busNos)
147+
{
148+
DDCA_Display_Identifier did;
149+
if (ffddca_create_busno_display_identifier(*busno, &did) >= 0)
150+
{
151+
DDCA_Display_Ref dref;
152+
if (ffddca_create_display_ref(did, &dref) >= 0)
153+
{
154+
FF_AUTO_FREE DDCA_Display_Info* dinfo = NULL;
155+
if (ffddca_get_display_info(dref, &dinfo) >= 0)
156+
detectWithDdcciImpl(&ddcutilData, result, dinfo);
157+
ffddca_free_display_ref(dref);
158+
}
159+
160+
ffddca_free_display_identifier(did);
161+
}
162+
}
163+
164+
return NULL;
165+
}
166+
105167
FF_AUTO_FREE DDCA_Display_Info_List* infoList = NULL;
106-
if (__builtin_expect(ffddca_get_display_info_list2(false, &infoList) < 0, 0))
168+
if (ffddca_get_display_info_list2(false, &infoList) < 0)
107169
return "ddca_get_display_info_list2(false, &infoList) failed";
108170

109171
if (infoList->ct == 0)
110172
return "No DDC/CI compatible displays found";
111173

112174
for (int index = 0; index < infoList->ct; ++index)
113175
{
114-
const DDCA_Display_Info* display = &infoList->info[index];
115-
116-
DDCA_Display_Handle handle;
117-
if (ffddca_open_display2(display->dref, false, &handle) >= 0)
118-
{
119-
DDCA_Any_Vcp_Value* vcpValue = NULL;
120-
if (ffddca_get_any_vcp_value_using_explicit_type(handle, 0x10 /*brightness*/, DDCA_NON_TABLE_VCP_VALUE, &vcpValue) >= 0)
121-
{
122-
assert(vcpValue->value_type == DDCA_NON_TABLE_VCP_VALUE);
123-
int current = VALREC_CUR_VAL(vcpValue), max = VALREC_MAX_VAL(vcpValue);
124-
ffddca_free_any_vcp_value(vcpValue);
125-
126-
FFBrightnessResult* brightness = (FFBrightnessResult*) ffListAdd(result);
127-
brightness->max = max;
128-
brightness->min = 0;
129-
brightness->current = current;
130-
ffStrbufInitS(&brightness->name, display->model_name);
131-
}
132-
ffddca_close_display(handle);
133-
}
176+
detectWithDdcciImpl(&ddcutilData, result, &infoList->info[index]);
134177
}
135178

136179
return NULL;

src/modules/brightness/brightness.c

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,10 @@ void ffInitBrightnessOptions(FFBrightnessOptions* options)
8888
{
8989
ffOptionInitModuleBaseInfo(&options->moduleInfo, FF_BRIGHTNESS_MODULE_NAME, ffParseBrightnessCommandOptions, ffParseBrightnessJsonObject, ffPrintBrightness, ffGenerateBrightnessJson, ffPrintBrightnessHelpFormat);
9090
ffOptionInitModuleArg(&options->moduleArgs);
91+
92+
#ifdef __linux__
93+
ffListInit(&options->busNos, sizeof(int));
94+
#endif
9195
}
9296

9397
bool ffParseBrightnessCommandOptions(FFBrightnessOptions* options, const char* key, const char* value)
@@ -103,6 +107,10 @@ bool ffParseBrightnessCommandOptions(FFBrightnessOptions* options, const char* k
103107
void ffDestroyBrightnessOptions(FFBrightnessOptions* options)
104108
{
105109
ffOptionDestroyModuleArg(&options->moduleArgs);
110+
111+
#ifdef __linux__
112+
ffListDestroy(&options->busNos);
113+
#endif
106114
}
107115

108116
void ffParseBrightnessJsonObject(FFBrightnessOptions* options, yyjson_val* module)
@@ -118,6 +126,22 @@ void ffParseBrightnessJsonObject(FFBrightnessOptions* options, yyjson_val* modul
118126
if (ffJsonConfigParseModuleArgs(key, val, &options->moduleArgs))
119127
continue;
120128

129+
#ifdef __linux__
130+
if(ffStrEqualsIgnCase(key, "busNos"))
131+
{
132+
if (!yyjson_is_arr(val)) continue;
133+
134+
yyjson_val* item;
135+
size_t idx, max;
136+
yyjson_arr_foreach(val, idx, max, item)
137+
{
138+
if (!yyjson_is_int(item)) continue;
139+
*(int*) ffListAdd(&options->busNos) = yyjson_get_int(item);
140+
}
141+
continue;
142+
}
143+
#endif
144+
121145
ffPrintError(FF_BRIGHTNESS_MODULE_NAME, 0, &options->moduleArgs, "Unknown JSON key %s", key);
122146
}
123147
}

src/modules/brightness/option.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,8 @@ typedef struct FFBrightnessOptions
88
{
99
FFModuleBaseInfo moduleInfo;
1010
FFModuleArgs moduleArgs;
11+
12+
#ifdef __linux__
13+
FFlist busNos;
14+
#endif
1115
} FFBrightnessOptions;

0 commit comments

Comments
 (0)