From 87b7dd250364ce51019e6a4bad2384f3cbc97053 Mon Sep 17 00:00:00 2001 From: rexy712 Date: Sun, 16 Dec 2018 14:27:58 -0800 Subject: [PATCH] Added option to not write to restore file and fixed a lot of restore file issues --- include/cmd.h | 10 ++- include/restore.h | 4 +- src/cmd.c | 23 ++++--- src/restore.c | 86 ++++++++++++------------- src/rexbacklight.c | 153 ++++++++++++++++++++------------------------- 5 files changed, 137 insertions(+), 139 deletions(-) diff --git a/include/cmd.h b/include/cmd.h index f037dac..ad5fa1b 100644 --- a/include/cmd.h +++ b/include/cmd.h @@ -29,6 +29,9 @@ #define OP_VERSION 254 #define OP_USAGE 255 +#define ARG_FLAG_NONE 0 +#define ARG_FLAG_NO_SAVE 1 + struct cmd_arg{ const char* lopt; const char* sopt; @@ -48,7 +51,11 @@ struct arg_values{ //NULL means all devices const char* device; - //What value to put in the backlight file + //starting brightness + int act_start; + //value to write in backlight file + int act_delta; + //output percentage float delta; //How many seconds to transition @@ -60,6 +67,7 @@ struct arg_values{ int operation; int num_values; }; + int flags; }; diff --git a/include/restore.h b/include/restore.h index 138bdd3..51f0935 100644 --- a/include/restore.h +++ b/include/restore.h @@ -24,8 +24,8 @@ #include "common.h" #include "cmd.h" -void save_restore_file(struct string_array* devices); -int restore_to_delta(struct arg_values* curr, RJP_value** root, int* try_restore); +void save_restore_file(struct string_array* devices, struct arg_values* args); +int restore_to_delta(struct arg_values* curr); void prep_restore(struct arg_values* a); RJP_value* find_matching_json_device(const char* name, RJP_value* root); RJP_value* read_restore_file(const char* file); diff --git a/src/cmd.c b/src/cmd.c index 4e1ce30..2a31421 100644 --- a/src/cmd.c +++ b/src/cmd.c @@ -58,6 +58,9 @@ #define RESTORE_LONG_OPT "--restore" #define RESTORE_SHORT_OPT "-R" #define RESTORE_XBACK_OPT NO_OPT +#define NO_SAVE_LONG_OPT "--no-save" +#define NO_SAVE_SHORT_OPT "-N" +#define NO_SAVE_XBACK_OPT NO_OPT #define DEVICE_DESC "select which device to control" #define FADE_DESC "change brightness over time interval" @@ -70,6 +73,7 @@ #define INC_DESC "increase backlight device by specified value" #define DEC_DESC "decrease backlight device by specified value" #define RESTORE_DESC "reassign previously saved device values" +#define NO_SAVE_DESC "do not write any data to the restore file" static inline int strcmp_handle_null(const char* one, const char* two){ if(!one) @@ -102,13 +106,14 @@ struct cmd_arg rexbacklight_args[] = { OPTION(LIST), #ifdef ENABLE_RESTORE_FILE OPTION(RESTORE), + OPTION(NO_SAVE), #endif OPTION(HELP), OPTION(VERSION) }; int rexbacklight_args_length = sizeof(rexbacklight_args) / sizeof(rexbacklight_args[0]); - +\ //Clean up a cmd_arg struct void free_cmd_args(struct arg_values* a){ if(!a->next) @@ -135,7 +140,7 @@ void free_cmd_args(struct arg_values* a){ }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}; + return (struct arg_values){.next = NULL, .device = NULL, .delta = 0, .fade_duration = 0, .fade_steps = 20, .operation = 0, .flags = 0}; } //Convert command line arguments to flags @@ -191,14 +196,14 @@ struct arg_values process_cmd_args(int argc, char** argv){ } else if(CHECK_OPTION(LIST, argv[i])){ - free_cmd_args(&ret); - ret.operation = OP_LIST; - ret.next = NULL; - return ret; + curr->operation = OP_LIST; } #ifdef ENABLE_RESTORE_FILE else if(CHECK_OPTION(RESTORE, argv[i])){ - ret.operation = OP_RESTORE; + curr->operation = OP_RESTORE; + } + else if(CHECK_OPTION(NO_SAVE, argv[i])){ + curr->flags |= ARG_FLAG_NO_SAVE; } #endif else if(!strcmp(argv[i], "max")){ @@ -290,7 +295,9 @@ struct arg_values process_cmd_args(int argc, char** argv){ curr->operation = ret.operation; if(!curr->delta) curr->delta = ret.delta; - + } + if(curr->flags == ARG_FLAG_NONE){ + curr->flags = ret.flags; } } } diff --git a/src/restore.c b/src/restore.c index d01dff8..70c9686 100644 --- a/src/restore.c +++ b/src/restore.c @@ -66,7 +66,6 @@ RJP_value* read_restore_file(const char* file){ int i; FILE* fp = fopen(file, "r"); if(!fp){ - fprintf(stderr, "Could not restore! No restore file found!\n"); return NULL; } @@ -83,6 +82,16 @@ RJP_value* read_restore_file(const char* file){ return root; } +static RJP_value* restore_file_handle(void){ + static RJP_value* rf = NULL; + if(!rf){ + char* f = restore_file(); + rf = read_restore_file(f); + free(f); + } + return rf; +} + RJP_value* find_matching_json_device(const char* name, RJP_value* root){ for(RJP_value* curr = rjp_get_member(root);curr;curr = rjp_next_member(curr)){ if(!strcmp(rjp_member_name(curr), name)){ @@ -93,17 +102,13 @@ RJP_value* find_matching_json_device(const char* name, RJP_value* root){ } //convert a restoration operation to a set operation -int restore_to_delta(struct arg_values* curr, RJP_value** root, int* try_restore){ - if(!*root && *try_restore){ - char* tmp = restore_file(); - *root = read_restore_file(tmp); - free(tmp); - if(!*root){ - *try_restore = 0; - return 0; - } +int restore_to_delta(struct arg_values* curr){ + RJP_value* root = restore_file_handle(); + if(!root){ + fprintf(stderr, "Could not restore! No restore file found!\n"); + return 0; } - RJP_value* match = find_matching_json_device(curr->device, *root); + RJP_value* match = find_matching_json_device(curr->device, root); if(!match){ fprintf(stderr, "No matching device '%s' in restore file!\n", curr->device); return 0; @@ -113,43 +118,38 @@ int restore_to_delta(struct arg_values* curr, RJP_value** root, int* try_restore return 1; } void prep_restore(struct arg_values* a){ - RJP_value* root = 0; - int try_restore = 1; for(struct arg_values* curr = a;curr;curr = curr->next){ - restore_to_delta(curr, &root, &try_restore); + restore_to_delta(curr); } - rjp_free_value(root); } -void save_restore_file(struct string_array* devices){ - RJP_value* root = rjp_init_json(); - for(size_t i = 0;i < devices->size;++i){ - if(chdir(devices->list[i])){ - io_error_2(IO_ERROR_OPEN, IO_ERROR_DIR, device_dir(), devices->list[i]); - return_value = RETVAL_INVALID_DIR; - continue; - } - size_t esc_name_len = rjp_escape_strlen(devices->list[i]); - char* esc_str = rjp_alloc(esc_name_len + 1); - rjp_escape_strcpy(esc_str, devices->list[i]); - - float curr = get_brightness(brightness_file()); - float max = get_brightness(max_brightness_file()); - if(return_value == RETVAL_INVALID_FILE && (!curr || !max)){ - rjp_add_member(root, 0, esc_str, 0, rjp_null()); - }else{ - rjp_add_member(root, 0, esc_str, 0, rjp_dfloat(curr/max*100)); - } - - if(chdir(device_dir())){ - io_error(IO_ERROR_OPEN, IO_ERROR_DIR, device_dir()); - return_value = RETVAL_INVALID_DIR; - rjp_free_value(root); - free(esc_str); - return; +void save_restore_file(struct string_array* devices, struct arg_values* args){ + RJP_value* rf = restore_file_handle(); + if(!rf) + rf = rjp_init_json(); + for(RJP_value* mem = rjp_get_member(rf);mem;mem = rjp_next_member(mem)){ + for(struct arg_values* curr = args->next, *prev = args;curr;prev = curr, curr = curr->next){ + if(curr->operation != OP_SET || curr->flags & ARG_FLAG_NO_SAVE){ + prev->next = curr->next; + free(curr); + curr = prev; + continue; + } + if(!strcmp(rjp_member_name(mem), curr->device)){ + rjp_set_value(mem, rjp_dfloat(curr->delta)); + prev->next = curr->next; + free(curr); + break; + } } } - char* tmp = rjp_to_json(root); + for(struct arg_values* curr = args->next;curr;curr = curr->next){ + if(curr->operation == OP_SET) + rjp_add_member(rf, curr->device, 0, rjp_dfloat(curr->delta)); + } + free_cmd_args(args); + + char* tmp = rjp_to_json(rf); char* rfil = restore_file(); FILE* restf = fopen(rfil, "w"); if(!restf){ @@ -160,7 +160,7 @@ void save_restore_file(struct string_array* devices){ } free(rfil); rjp_free(tmp); - rjp_free_value(root); + rjp_free_value(rf); } diff --git a/src/rexbacklight.c b/src/rexbacklight.c index db61ae1..eaa115a 100644 --- a/src/rexbacklight.c +++ b/src/rexbacklight.c @@ -163,14 +163,14 @@ void sleep_for(double time){ } //update brightness incrementally over requested millisecond time interval -void fade_out(struct arg_values* arg, int iv, int fv){ +void fade_out(struct arg_values* arg){ FILE* fd; double start, end; double tdelta = 0; //amount of time that has passed in ms - float value = iv; //current value to write to file + float value = arg->act_start; //current value to write to file double step_delta = (double)arg->fade_duration / arg->fade_steps; double step_inc = step_delta; - float brdelta = (float)(fv - iv) / arg->fade_steps; //amount brightness needs to change per iteration + float brdelta = (float)(arg->act_delta - arg->act_start) / arg->fade_steps; //amount brightness needs to change per iteration while(arg->fade_duration > tdelta){ //write @@ -205,106 +205,89 @@ void fade_out(struct arg_values* arg, int iv, int fv){ return_value = RETVAL_INVALID_FILE; return; } - fprintf(fd, "%d", fv); + fprintf(fd, "%d", arg->act_delta); fclose(fd); + if(chdir(device_dir())){ + io_error(IO_ERROR_OPEN, IO_ERROR_DIR, device_dir()); + return_value = RETVAL_INVALID_DIR; + return; + } } -//Write value to device files -int do_assignment(struct arg_values* args){ - for(;args;args = args->next){ - if(chdir(args->device)){ - io_error_2(IO_ERROR_OPEN, IO_ERROR_DIR, device_dir(), args->device); - return_value = RETVAL_INVALID_DIR; - continue; - } - int start = get_brightness(brightness_file()); - int out = process_op(args, 0, start, get_brightness(max_brightness_file())); - fade_out(args, start, out); - if(chdir(device_dir())){ - io_error(IO_ERROR_OPEN, IO_ERROR_DIR, device_dir()); - return RETVAL_INVALID_DIR; - } +int prep_offset(struct arg_values* args){ + if(chdir(args->device)){ + io_error_2(IO_ERROR_OPEN, IO_ERROR_DIR, device_dir(), args->device); + return RETVAL_INVALID_DIR; } - return return_value; + args->act_start = get_brightness(brightness_file()); + float act_max = get_brightness(max_brightness_file()); + args->act_delta = process_op(args, 0, args->act_start, act_max); + float start_pec = (args->act_start / act_max) * 100.0; + if(args->operation == OP_INC){ + args->delta = start_pec + args->delta; + }else if(args->operation == OP_DEC){ + args->delta = start_pec - args->delta; + } + if(args->delta > 100) + args->delta = 100; + else if(args->delta < 0) + args->delta = 0; + args->operation = OP_SET; + //chdir back in do_assignment + return 0; } //Run get operation int do_get(struct arg_values* args){ - for(;args;args = args->next){ - float curr, max; - if(chdir(args->device)){ - io_error_2(IO_ERROR_OPEN, IO_ERROR_DIR, device_dir(), args->device); - return_value = RETVAL_INVALID_DIR; - continue; - } - curr = get_brightness(brightness_file()); - max = get_brightness(max_brightness_file()); - if(return_value == RETVAL_INVALID_FILE && (!curr || !max)){ - fprintf(stdout, "%s", args->device); - }else{ - fprintf(stdout, "%-25s %.2f\n", args->device, curr / max * 100); - } - if(chdir(device_dir())){ - io_error(IO_ERROR_OPEN, IO_ERROR_DIR, device_dir()); - return RETVAL_INVALID_DIR; - } + float curr, max; + if(chdir(args->device)){ + io_error_2(IO_ERROR_OPEN, IO_ERROR_DIR, device_dir(), args->device); + return RETVAL_INVALID_DIR; + } + curr = get_brightness(brightness_file()); + max = get_brightness(max_brightness_file()); + if(return_value == RETVAL_INVALID_FILE && (!curr || !max)){ + fprintf(stdout, "%s", args->device); + }else{ + fprintf(stdout, "%-25s %.2f\n", args->device, curr / max * 100); + } + if(chdir(device_dir())){ + io_error(IO_ERROR_OPEN, IO_ERROR_DIR, device_dir()); + return RETVAL_INVALID_DIR; } return return_value; } //Run list operation void do_list(struct arg_values* args){ - for(;args;args = args->next){ - printf("%s\n", args->device); - } -} - -//move next arg in src list to next arg in dest list -void extract_next_arg(struct arg_values* dest, struct arg_values* src){ - dest->next = src->next; - src->next = src->next->next; - dest->next->next = NULL; -} - -//remove all args in src which have the specified operation and append them to dest -struct arg_values* extract_operation(int operation, struct arg_values* dest, struct arg_values* src){ - struct arg_values* curr_dest = dest; - dest->next = NULL; - for(struct arg_values* curr_src = src;curr_src->next;){ - if(curr_src->next->operation & operation){ - extract_next_arg(curr_dest, curr_src); - curr_dest = curr_dest->next; - }else{ - curr_src = curr_src->next; - } - } - return curr_dest; + printf("%s\n", args->device); } //Run requested operation on a per device basis void run_device_operations(struct arg_values* a){ - struct arg_values* curr; - struct arg_values current_op_args = {0}; - - //list - extract_operation(OP_LIST, ¤t_op_args, a); - do_list(current_op_args.next); - free_cmd_args(¤t_op_args); - - //get - extract_operation(OP_GET, ¤t_op_args, a); - return_value = do_get(current_op_args.next); - free_cmd_args(¤t_op_args); - - //assignment + for(a = a->next;a;a = a->next){ + switch(a->operation){ + case OP_LIST: + do_list(a); + break; + case OP_GET: + return_value = do_get(a); + break; #ifdef ENABLE_RESTORE_FILE - curr = extract_operation(OP_RESTORE, ¤t_op_args, a); - prep_restore(current_op_args.next); + case OP_RESTORE: + if(!restore_to_delta(a)){ + continue; + } #endif - extract_operation(OP_SET | OP_INC | OP_DEC, curr, a); - return_value = do_assignment(current_op_args.next); - free_cmd_args(¤t_op_args); - + case OP_INC: + case OP_DEC: + case OP_SET: + if(prep_offset(a)) + break; + fade_out(a); + break; + }; + } } //If a global operation is requested, run this to fill arg with all devices, each with the global operation @@ -317,6 +300,7 @@ void populate_args(struct arg_values* arg, struct string_array* devices){ curr->next->fade_duration = arg->fade_duration; curr->next->fade_steps = arg->fade_steps; curr->next->operation = arg->operation; + curr->next->flags = arg->flags; curr = curr->next; } curr->next = NULL; @@ -378,10 +362,9 @@ int main(int argc, char** argv){ } run_device_operations(&args); #ifdef ENABLE_RESTORE_FILE - save_restore_file(&device_names); + save_restore_file(&device_names, &args); //performs cleanup on args #endif free_string_array(&device_names); - free_cmd_args(&args); return return_value; }