Skip to content

Commit

Permalink
Use percentages everywhere for brightness values
Browse files Browse the repository at this point in the history
  • Loading branch information
sidevesh committed Jun 27, 2023
1 parent 1e7c8be commit a980971
Show file tree
Hide file tree
Showing 7 changed files with 77 additions and 68 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Luminance
A simple GTK application to control brightness of external displays supporting DDC/CI
A simple GTK application to control brightness of displays including external displays supporting DDC/CI

## Dependencies
- ddcutil library package (typically libddcutil or libddcutil-dev if not already installed with ddcutil)
Expand Down
2 changes: 1 addition & 1 deletion info.c
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#define APP_INFO_VERSION_NUMBER "1.0.0"
#define APP_INFO_PACKAGE_NAME "com.sidevesh.Luminance"
#define APP_INFO_DISPLAY_NAME "Luminance"
#define APP_INFO_DESCRIPTION "A simple GTK application to control brightness of external displays supporting DDC/CI"
#define APP_INFO_DESCRIPTION "A simple GTK application to control brightness of displays including external displays supporting DDC/CI"
#define APP_INFO_SOURCE_REPOSITORY_TITLE "GitHub"
#define APP_INFO_SOURCE_REPOSITORY_LINK "https://github.com/sidevesh/Luminance"
#define APP_INFO_LICENSE GTK_LICENSE_GPL_3_0
Expand Down
2 changes: 1 addition & 1 deletion install_files/com.sidevesh.Luminance.desktop
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[Desktop Entry]
Name=Luminance
Comment=A simple GTK application to control brightness of external displays supporting DDC/CI
Comment=A simple GTK application to control brightness of displays including external displays supporting DDC/CI
Icon=video-display
Exec=/usr/bin/com.sidevesh.Luminance
Terminal=false
Expand Down
17 changes: 6 additions & 11 deletions src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -57,10 +57,8 @@ int ensure_displays_are_present_in_cli() {
// Function to list all displays and their brightness
int list_displays_in_cli() {
for (guint index = 0; index < displays_count(); index++) {
const gchar *label = get_display_name(index);
guint16 brightness = get_display_brightness(index);
guint16 max_brightness = get_display_max_brightness(index);
gdouble brightness_percentage = (brightness * 100.0) / max_brightness;
gchar *label = get_display_name(index);
gdouble brightness_percentage = get_display_brightness_percentage(index);
printf("Display %d: Label: %s, Brightness: %.2f%%\n", index + 1, label, brightness_percentage);
}

Expand All @@ -71,9 +69,8 @@ int list_displays_in_cli() {
int get_display_brightness_in_cli(guint display_number) {
for (guint index = 0; index < displays_count(); index++) {
if ((index + 1) == display_number) {
guint16 brightness = get_display_brightness(index);
guint16 max_brightness = get_display_max_brightness(index);
printf("%.2f%%\n", (brightness * 100.0) / max_brightness);
gdouble brightness_percentage = get_display_brightness_percentage(index);
printf("%.2f%%\n", brightness_percentage);
return 0;
}
}
Expand All @@ -85,9 +82,7 @@ int get_display_brightness_in_cli(guint display_number) {
void set_brightness_percentage_in_cli(guint display_index, double brightness_percentage) {
for (guint index = 0; index < displays_count(); index++) {
if (index == display_index) {
guint16 max_brightness = get_display_max_brightness(index);
guint16 brightness = (guint16)(brightness_percentage * max_brightness / 100.0);
set_display_brightness(index, brightness);
set_display_brightness_percentage(index, brightness_percentage);
return;
}
}
Expand All @@ -105,7 +100,7 @@ int set_display_brightness_if_needed_in_cli(guint display_number, guint brightne

for (guint index = 0; index < displays_count(); index++) {
if (display_number == 0 || (index + 1) == display_number) {
gdouble current_brightness_percentage = (get_display_brightness(index) * 100.0) / get_display_max_brightness(index);
gdouble current_brightness_percentage = get_display_brightness_percentage(index);
gdouble final_brightness_percentage = brightness_percentage;
if (get_is_brightness_linked() && display_number == 0 && linked_all_displays_brightness_percentage != -1) {
final_brightness_percentage = linked_all_displays_brightness_percentage;
Expand Down
101 changes: 59 additions & 42 deletions src/states/displays.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,32 +39,41 @@ void _initialize_displays(gboolean first_time_loading) {
time_t start_loading_displays_time;
time(&start_loading_displays_time);

if (!first_time_loading) {
ddcbc_display_list_free(_display_list);
}

_display_list_instance = ddcbc_display_list_init(FALSE);
_display_list = &_display_list_instance;

// Populate internal backlight display directories
guint internal_backlight_count = 0;
DIR* dir = opendir("/sys/class/backlight");
if (dir != NULL) {
struct dirent* entry;
while ((entry = readdir(dir)) != NULL && internal_backlight_count < MAX_INTERNAL_BACKLIGHT_DISPLAYS) {
if (
entry->d_type == DT_DIR &&
strcmp(entry->d_name, ".") != 0 &&
strcmp(entry->d_name, "..") != 0
) {
strcmp(entry->d_name, ".") != 0 &&
strcmp(entry->d_name, "..") != 0
) {
_internal_backlight_display_directories[internal_backlight_count] = strdup(entry->d_name);
// insert the internal backlight display into the display_indexes array
display_indexes[internal_backlight_count].type = DISPLAY_TYPE_INTERNAL_BACKLIGHT;
display_indexes[internal_backlight_count].index = internal_backlight_count;
internal_backlight_count++;
}
}
_internal_backlight_display_directories_count = internal_backlight_count;
_internal_backlight_display_directories_count = internal_backlight_count;
closedir(dir);
}

if (!first_time_loading) {
ddcbc_display_list_free(_display_list);
}

_display_list_instance = ddcbc_display_list_init(FALSE);
_display_list = &_display_list_instance;

// insert all DDC displays into the display_indexes array
guint ddc_display_count = 0;
for (guint index = 0; index < _display_list->ct; index++) {
display_indexes[internal_backlight_count + ddc_display_count].type = DISPLAY_TYPE_DDC;
display_indexes[internal_backlight_count + ddc_display_count].index = index;
ddc_display_count++;
}

time_t end_loading_displays_time;
time(&end_loading_displays_time);
_last_displays_load_time = difftime(end_loading_displays_time, start_loading_displays_time);
Expand Down Expand Up @@ -106,6 +115,25 @@ ddcbc_display* _get_ddcbc_display(guint index) {
return ddcbc_display_list_get(_display_list, display_index.index);
}

guint16 _get_display_max_brightness_value(guint index) {
GlobalDisplayIndex display_index = display_indexes[index];
if (display_index.type == DISPLAY_TYPE_INTERNAL_BACKLIGHT) {
gchar max_brightness_file_path[256];
snprintf(max_brightness_file_path, sizeof(max_brightness_file_path), "/sys/class/backlight/%s/max_brightness", _internal_backlight_display_directories[display_index.index]);

FILE* file = fopen(max_brightness_file_path, "r");
if (file != NULL) {
guint max_brightness;
fscanf(file, "%u", &max_brightness);
fclose(file);
return max_brightness;
}
} else {
ddcbc_display* display = _get_ddcbc_display(index);
return display->max_val;
}
}

void load_displays(void (*on_load_started_callback)(), void (*on_load_completed_callback)()) {
_refresh_displays_with_callbacks(TRUE, on_load_started_callback, on_load_completed_callback);
}
Expand Down Expand Up @@ -133,74 +161,63 @@ int last_displays_load_time() {
char* get_display_name(guint index) {
GlobalDisplayIndex display_index = display_indexes[index];
if (display_index.type == DISPLAY_TYPE_INTERNAL_BACKLIGHT) {
return "Built-in display %d", display_index.index + 1;
if (_internal_backlight_display_directories_count == 1) {
return "Built-in display";
}
gchar *display_name = malloc(256);
snprintf(display_name, 256, "Built-in display %d", display_index.index + 1);
return display_name;
} else {
ddcbc_display* display = _get_ddcbc_display(index);
return display->info.model_name;
}
}

int get_display_brightness(guint index) {
gdouble get_display_brightness_percentage(guint index) {
GlobalDisplayIndex display_index = display_indexes[index];
guint16 max_brightness_value = _get_display_max_brightness_value(index);
if (display_index.type == DISPLAY_TYPE_INTERNAL_BACKLIGHT) {
gchar brightness_file_path[256];
snprintf(brightness_file_path, sizeof(brightness_file_path), "/sys/class/backlight/%s/brightness", _internal_backlight_display_directories[display_index.index]);

FILE* file = fopen(brightness_file_path, "r");
if (file != NULL) {
guint brightness;
fscanf(file, "%u", &brightness);
fscanf(file, "%u", &brightness);
fclose(file);
return brightness;
return brightness * 100.0 / max_brightness_value;
}
} else {
ddcbc_display* display = _get_ddcbc_display(index);
return display->last_val;
}
}

int get_display_max_brightness(guint index) {
GlobalDisplayIndex display_index = display_indexes[index];
if (display_index.type == DISPLAY_TYPE_INTERNAL_BACKLIGHT) {
gchar max_brightness_file_path[256];
snprintf(max_brightness_file_path, sizeof(max_brightness_file_path), "/sys/class/backlight/%s/max_brightness", _internal_backlight_display_directories[display_index.index]);

FILE* file = fopen(max_brightness_file_path, "r");
if (file != NULL) {
guint max_brightness;
fscanf(file, "%u", &max_brightness);
fclose(file);
return max_brightness;
}
} else {
ddcbc_display* display = _get_ddcbc_display(index);
return display->max_val;
return display->last_val * 100.0 / max_brightness_value;
}
}

void set_display_brightness(guint index, guint16 brightness) {
void set_display_brightness_percentage(guint index, gdouble brightness_percentage) {
GlobalDisplayIndex display_index = display_indexes[index];
guint16 max_brightness_value = _get_display_max_brightness_value(index);
guint16 brightness_value = (guint16)(brightness_percentage * max_brightness_value / 100);
if (display_index.type == DISPLAY_TYPE_INTERNAL_BACKLIGHT) {
gchar brightness_file_path[256];
snprintf(brightness_file_path, sizeof(brightness_file_path), "/sys/class/backlight/%s/brightness", _internal_backlight_display_directories[display_index.index]);

FILE* file = fopen(brightness_file_path, "w");
if (file != NULL) {
fprintf(file, "%u", brightness);
fprintf(file, "%u", brightness_value);
fclose(file);
} else {
fprintf(stderr, "Error opening brightness file for writing: %s\n", brightness_file_path);
}
} else {
ddcbc_display* display = _get_ddcbc_display(index);
DDCBC_Status rc = ddcbc_display_set_brightness(display, brightness);
DDCBC_Status rc = ddcbc_display_set_brightness(display, brightness_value);

if (rc == 1) {
fprintf(stderr, "Partial success in setting the brightness of display no %d to %u. Code: %d\n",
display->info.dispno, brightness, rc);
display->info.dispno, brightness_value, rc);
} else if (rc != 0) {
fprintf(stderr, "An error occurred when setting the brightness of display no %d to %u. Code: %d\n",
display->info.dispno, brightness, rc);
display->info.dispno, brightness_value, rc);
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/ui/components/display_brightness_scale.c
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#include <gtk/gtk.h>
#include "../constants/main.c"

GtkWidget* get_display_brightness_scale(guint16 last_value, guint16 max_value) {
GtkWidget* get_display_brightness_scale(gdouble last_value, gdouble max_value) {
GtkWidget *scale = gtk_scale_new_with_range(GTK_ORIENTATION_HORIZONTAL, 0, max_value, 1);
gtk_range_set_value(GTK_RANGE(scale), last_value);
gtk_scale_set_value_pos(GTK_SCALE(scale), GTK_POS_RIGHT);
Expand Down
19 changes: 8 additions & 11 deletions src/ui/screens/show_displays.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,19 +19,18 @@ gboolean _set_brightness(GtkWidget *widget, GdkEvent *event, guint data) {

display_section *display_section = _display_sections[index_of_display_section];

guint16 new_value = gtk_range_get_value(GTK_RANGE(widget));
set_display_brightness(display_section->display_index, new_value);
guint16 new_brightness_percentage = gtk_range_get_value(GTK_RANGE(widget));
set_display_brightness_percentage(display_section->display_index, new_brightness_percentage);

if (get_is_brightness_linked()) {
for (guint index = 0; index < _display_sections_count; index++) {
GtkWidget *scale = _display_sections[index]->scale;
gdouble linked_display_new_value = (1.0 * new_value / get_display_max_brightness(display_section->display_index)) * get_display_max_brightness(_display_sections[index]->display_index);

if (_display_sections[index]->display_index == display_section->display_index) {
continue;
}
gtk_range_set_value(GTK_RANGE(scale), linked_display_new_value);
set_display_brightness(_display_sections[index]->display_index, linked_display_new_value);
gtk_range_set_value(GTK_RANGE(scale), new_brightness_percentage);
set_display_brightness_percentage(_display_sections[index]->display_index, new_brightness_percentage);
}
}

Expand Down Expand Up @@ -59,15 +58,13 @@ void _link_brightness(GtkToggleButton *link_brightness_check_button) {

gdouble max_scale_percentage = 0;
for (guint index = 0; index < _display_sections_count; index++) {
guint value = gtk_range_get_value(GTK_RANGE(_display_sections[index]->scale));
gdouble percentage_value = (1.0 * value / get_display_max_brightness(index)) * 100;
guint percentage_value = gtk_range_get_value(GTK_RANGE(_display_sections[index]->scale));
max_scale_percentage = percentage_value > max_scale_percentage ? percentage_value : max_scale_percentage;
}

for (guint index = 0; index < _display_sections_count; index++) {
guint16 new_value = max_scale_percentage * get_display_max_brightness(index) / 100;
gtk_range_set_value(GTK_RANGE(_display_sections[index]->scale), new_value);
set_display_brightness(_display_sections[index]->display_index, new_value);
gtk_range_set_value(GTK_RANGE(_display_sections[index]->scale), max_scale_percentage);
set_display_brightness_percentage(_display_sections[index]->display_index, max_scale_percentage);
}
}

Expand All @@ -86,7 +83,7 @@ GtkWidget* get_show_displays_screen() {
display_section *display_section_instance = malloc(sizeof(display_section));
display_section_instance->display_index = index;
display_section_instance->label = get_display_label(get_display_name(index));
display_section_instance->scale = get_display_brightness_scale(get_display_brightness(index), get_display_max_brightness(index));
display_section_instance->scale = get_display_brightness_scale(get_display_brightness_percentage(index), 100.0);
g_signal_connect(display_section_instance->scale, "button-release-event", G_CALLBACK(_set_brightness), GUINT_TO_POINTER(index));
g_signal_connect(display_section_instance->scale, "scroll-event", G_CALLBACK(_set_brightness), GUINT_TO_POINTER(index));
g_signal_connect(display_section_instance->scale, "value-changed", G_CALLBACK(_update_display_brightness_scales), GUINT_TO_POINTER(index));
Expand Down

0 comments on commit a980971

Please sign in to comment.