From f754f6422c22bf80018897135034e46ebe3acc9d Mon Sep 17 00:00:00 2001 From: rexy712 Date: Sun, 28 Jan 2018 13:22:21 -0800 Subject: [PATCH] Fading now works --- TODO | 2 +- include/cmd.h | 2 ++ makefile | 4 ++-- src/cmd.c | 36 ++++++++++++++++++++--------- src/rexbacklight.c | 56 +++++++++++++++++++++++++++++++++++++++------- 5 files changed, 78 insertions(+), 22 deletions(-) diff --git a/TODO b/TODO index 9e2fabc..047493c 100644 --- a/TODO +++ b/TODO @@ -2,5 +2,5 @@ #List devices #Query backlight percentage (get) xbacklight compat option (-get/-set/-inc/-dec/-help/-time/-steps) -allow fade in and fade out +#allow fade in and fade out a lot of cleanup diff --git a/include/cmd.h b/include/cmd.h index 89e9444..993b81d 100644 --- a/include/cmd.h +++ b/include/cmd.h @@ -48,6 +48,8 @@ struct arg_values{ //How many seconds to transition int fade_duration; + int fade_steps; + unsigned char operation; }; diff --git a/makefile b/makefile index 91d7f1b..0c2c2f6 100644 --- a/makefile +++ b/makefile @@ -55,9 +55,9 @@ $(foreach dir,$(SOURCE_DIRS),$(eval $(call GENERATE_OBJECTS,$(dir)))) $(OBJECTS): | $(OBJDIR) $(DEPDIR) $(OBJDIR): - mkdir "$@" + mkdir -p "$@" $(DEPDIR): - mkdir "$@" + mkdir -p "$@" .PHONY: clean clean: diff --git a/src/cmd.c b/src/cmd.c index 41c9bee..afc18d3 100644 --- a/src/cmd.c +++ b/src/cmd.c @@ -27,6 +27,8 @@ #define GET_SHORT_OPT "-g" #define FADE_LONG_OPT "--fade" #define FADE_SHORT_OPT "-f" +#define STEPS_LONG_OPT "--steps" +#define STEPS_SHORT_OPT "-s" #define DEVICE_LONG_OPT "--device" #define DEVICE_SHORT_OPT "-d" #define LIST_LONG_OPT "--list" @@ -39,7 +41,8 @@ struct cmd_arg rexbacklight_args[] = { {DEVICE_LONG_OPT, DEVICE_SHORT_OPT, "select which device to control"}, - {FADE_LONG_OPT, FADE_SHORT_OPT, "TODO: change brightness over time interval"}, + {FADE_LONG_OPT, FADE_SHORT_OPT, "change brightness over time interval"}, + {STEPS_LONG_OPT, STEPS_SHORT_OPT, "number of steps over which to fade"}, {GET_LONG_OPT, GET_SHORT_OPT, "print current brightness level to stdout"}, {LIST_LONG_OPT, LIST_SHORT_OPT, "print device names to stdout and exit"}, {HELP_LONG_OPT, HELP_SHORT_OPT, "print this help message and exit"} @@ -54,24 +57,28 @@ void free_cmd_args(struct arg_values* a){ free(a->next); } -#define CHECK_NEXT_ARG(rval) \ +#define CHECK_NEXT_ARG() \ do{ \ if(i == argc - 1){ \ fprintf(stderr, "Missing argument to '%s'\n\n", argv[i]); \ free_cmd_args(&ret); \ - usage(rval); \ + usage(RETVAL_MISSING_OPTION); \ } \ }while(0) -#define UNRECOGNIZED_OPTION(rval) \ +#define UNRECOGNIZED_OPTION() \ do{ \ fprintf(stderr, "Unrecognized command line option '%s'\n\n", argv[i]); \ free_cmd_args(&ret); \ - usage(rval); \ + usage(RETVAL_UNRECOGNIZED_OPTION); \ }while(0); +struct arg_values init_arg_values(void){ + return (struct arg_values){.next = NULL, .device = NULL, .delta = 0, .fade_duration = 0, .fade_steps = 20, .operation = 0}; +} + //Convert command line arguments to flags struct arg_values process_cmd_args(int argc, char** argv){ - struct arg_values ret = {0}; + struct arg_values ret = init_arg_values(); struct arg_values* curr = &ret; //Skip argv[0] @@ -83,14 +90,21 @@ struct arg_values process_cmd_args(int argc, char** argv){ continue; }else if(CHECK_OPTION(FADE, argv[i])){ - CHECK_NEXT_ARG(-5); + CHECK_NEXT_ARG(); curr->fade_duration = strtol(argv[++i], NULL, 0); continue; } + else if(CHECK_OPTION(STEPS, argv[i])){ + CHECK_NEXT_ARG(); + curr->fade_steps = strtol(argv[++i], NULL, 0); + continue; + } + else if(CHECK_OPTION(DEVICE, argv[i])){ - CHECK_NEXT_ARG(-5); - curr->next = calloc(1, sizeof(struct arg_values)); + CHECK_NEXT_ARG(); + curr->next = malloc(sizeof(struct arg_values)); + *(curr->next) = init_arg_values(); curr = curr->next; curr->device = argv[++i]; continue; @@ -130,7 +144,7 @@ struct arg_values process_cmd_args(int argc, char** argv){ else if(argv[i][0] == '-'){ //If we get a '-' followed by not a number, it's not a known option if(argv[i][1] < '0' || argv[i][1] > '9'){ - UNRECOGNIZED_OPTION(RETVAL_UNRECOGNIZED_OPTION); + UNRECOGNIZED_OPTION(); //If we get a '-' followed by a number, it's a decrement request }else{ @@ -144,7 +158,7 @@ struct arg_values process_cmd_args(int argc, char** argv){ if(argv[i][j] == '\0') break; if(argv[i][j] < '0' || argv[i][j] > '9') - UNRECOGNIZED_OPTION(RETVAL_UNRECOGNIZED_OPTION); + UNRECOGNIZED_OPTION(); } curr->operation = OP_SET; curr->delta = atof(argv[i]); diff --git a/src/rexbacklight.c b/src/rexbacklight.c index 1af3b60..74f04ea 100644 --- a/src/rexbacklight.c +++ b/src/rexbacklight.c @@ -15,11 +15,14 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ +#define _DEFAULT_SOURCE + #include #include #include #include #include +#include #include "common.h" #include "cmd.h" @@ -116,16 +119,53 @@ float get_brightness(const char* file){ return atof(buff); } +//update brightness incrementally over requested millisecond time interval +void fade_out(int iv, int fv, int ms_duration, int steps){ + FILE* fd; + struct timeval start, end; + double tdelta = 0; //amount of time that has passed + float value = iv; //current value to write to file + int step_delta = ms_duration / steps; + int step_inc = step_delta; + float brdelta = (float)(fv - iv) / steps; //amount brightness needs to change overall + + while(ms_duration > tdelta){ + //write + gettimeofday(&start, NULL); + fd = fopen(backlight_file, "w+"); + if(!fd){ + io_error_2(IO_ERROR_OPEN, IO_ERROR_FILE, backlight_dir, backlight_file); + return; + } + fprintf(fd, "%d", (int)value); + fclose(fd); + gettimeofday(&end, NULL); + + //calc time delta + tdelta += (((end.tv_sec * 1000.0) + (end.tv_usec / 1000.0)) - ((start.tv_sec * 1000.0) + (start.tv_usec / 1000.0))); + + //calc next value to write + value += brdelta; + + //waste excess time until next step + if(step_delta > tdelta){ + usleep((step_delta - tdelta) * 1000); + tdelta = step_delta; + } + //calc end of next step + step_delta += step_inc; + } + fd = fopen(backlight_file, "w+"); + fprintf(fd, "%d", fv); + + fclose(fd); +} + //Write value to backlight files void do_assignment(struct arg_values* arg){ - int out = process_op(arg, 0, get_brightness(backlight_file), get_brightness(max_backlight_file)); - FILE* bright = fopen(backlight_file, "w+"); - if(!bright){ - io_error_2(IO_ERROR_OPEN, IO_ERROR_FILE, backlight_dir, backlight_file); - return; - } - fprintf(bright, "%d", out); - fclose(bright); + int start = get_brightness(backlight_file); + int out = process_op(arg, 0, start, get_brightness(max_backlight_file)); + fade_out(start, out, arg->fade_duration, arg->fade_steps); } //Run get operation