Refactored how operations are carried out
This commit is contained in:
parent
04dcd0684a
commit
1d5a5d9d69
@ -40,11 +40,6 @@
|
|||||||
#define IO_ERROR_READ "read"
|
#define IO_ERROR_READ "read"
|
||||||
#define IO_ERROR_WRITE "write to"
|
#define IO_ERROR_WRITE "write to"
|
||||||
|
|
||||||
void io_error(const char* error, const char* type, const char* name);
|
|
||||||
void io_error_2(const char* error, const char* type, const char* name, const char* name2);
|
|
||||||
void io_error_3(const char* error, const char* type, const char* name, const char* name2, const char* name3);
|
|
||||||
|
|
||||||
|
|
||||||
extern int return_value;
|
extern int return_value;
|
||||||
|
|
||||||
struct string_array{
|
struct string_array{
|
||||||
@ -53,7 +48,11 @@ struct string_array{
|
|||||||
};
|
};
|
||||||
void free_string_array(struct string_array* s);
|
void free_string_array(struct string_array* s);
|
||||||
|
|
||||||
|
void io_error(const char* error, const char* type, const char* name);
|
||||||
|
void io_error_2(const char* error, const char* type, const char* name, const char* name2);
|
||||||
|
void io_error_3(const char* error, const char* type, const char* name, const char* name2, const char* name3);
|
||||||
void mem_error(void);
|
void mem_error(void);
|
||||||
|
|
||||||
_Noreturn void version(void);
|
_Noreturn void version(void);
|
||||||
_Noreturn void usage(int exit_val);
|
_Noreturn void usage(int exit_val);
|
||||||
|
|
||||||
|
|||||||
@ -25,8 +25,7 @@
|
|||||||
#include "cmd.h"
|
#include "cmd.h"
|
||||||
|
|
||||||
void save_restore_file(struct string_array* devices);
|
void save_restore_file(struct string_array* devices);
|
||||||
void all_restore(void);
|
int restore_to_delta(struct arg_values* curr, RJP_value** root, int* try_restore);
|
||||||
int individual_restore(struct arg_values* curr, RJP_value** root, int* try_restore);
|
|
||||||
RJP_value* find_matching_json_device(const char* name, RJP_value* root);
|
RJP_value* find_matching_json_device(const char* name, RJP_value* root);
|
||||||
RJP_value* read_restore_file(const char* file);
|
RJP_value* read_restore_file(const char* file);
|
||||||
|
|
||||||
|
|||||||
@ -69,7 +69,7 @@
|
|||||||
#define SET_DESC "set backlight device to specified value"
|
#define SET_DESC "set backlight device to specified value"
|
||||||
#define INC_DESC "increase backlight device by specified value"
|
#define INC_DESC "increase backlight device by specified value"
|
||||||
#define DEC_DESC "decrease backlight device by specified value"
|
#define DEC_DESC "decrease backlight device by specified value"
|
||||||
#define RESTORE_DESC "reassign previously saved backlight values"
|
#define RESTORE_DESC "reassign previously saved device values"
|
||||||
|
|
||||||
int strcmp_handle_null(const char* one, const char* two){
|
int strcmp_handle_null(const char* one, const char* two){
|
||||||
if(!one)
|
if(!one)
|
||||||
@ -119,7 +119,6 @@ struct cmd_arg rexbacklight_args[] = {
|
|||||||
};
|
};
|
||||||
#endif //XBACKLIGHT_COMPAT_OPTIONS
|
#endif //XBACKLIGHT_COMPAT_OPTIONS
|
||||||
|
|
||||||
|
|
||||||
int rexbacklight_args_length = sizeof(rexbacklight_args) / sizeof(rexbacklight_args[0]);
|
int rexbacklight_args_length = sizeof(rexbacklight_args) / sizeof(rexbacklight_args[0]);
|
||||||
|
|
||||||
//Clean up a cmd_arg struct
|
//Clean up a cmd_arg struct
|
||||||
|
|||||||
@ -92,8 +92,8 @@ RJP_value* find_matching_json_device(const char* name, RJP_value* root){
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
//run restore on individual device
|
//convert a restoration operation to a set operation
|
||||||
int individual_restore(struct arg_values* curr, RJP_value** root, int* try_restore){
|
int restore_to_delta(struct arg_values* curr, RJP_value** root, int* try_restore){
|
||||||
if(!*root && *try_restore){
|
if(!*root && *try_restore){
|
||||||
char* tmp = restore_file();
|
char* tmp = restore_file();
|
||||||
*root = read_restore_file(tmp);
|
*root = read_restore_file(tmp);
|
||||||
@ -113,24 +113,6 @@ int individual_restore(struct arg_values* curr, RJP_value** root, int* try_resto
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
//run restore on all devices
|
|
||||||
void all_restore(void){
|
|
||||||
char* rfil = restore_file();
|
|
||||||
RJP_value* root = read_restore_file(rfil);
|
|
||||||
free(rfil);
|
|
||||||
if(!root)
|
|
||||||
return;
|
|
||||||
struct arg_values tmp = {.next = NULL,
|
|
||||||
.fade_duration = 0,
|
|
||||||
.fade_steps = 1,
|
|
||||||
.operation = OP_SET};
|
|
||||||
for(RJP_value* curr = rjp_get_member(root);curr;curr = rjp_next_member(curr)){
|
|
||||||
tmp.device = rjp_member_name(curr);
|
|
||||||
tmp.delta = rjp_value_dfloat(curr);
|
|
||||||
individual_device_op(&tmp);
|
|
||||||
}
|
|
||||||
rjp_free_value(root);
|
|
||||||
}
|
|
||||||
void save_restore_file(struct string_array* devices){
|
void save_restore_file(struct string_array* devices){
|
||||||
RJP_value* root = rjp_init_json();
|
RJP_value* root = rjp_init_json();
|
||||||
for(size_t i = 0;i < devices->size;++i){
|
for(size_t i = 0;i < devices->size;++i){
|
||||||
|
|||||||
@ -35,12 +35,13 @@
|
|||||||
#include "restore.h"
|
#include "restore.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//name of the program being run so that we print the correct name in the usage
|
|
||||||
|
|
||||||
#ifdef REXBACKLIGHT
|
#ifdef REXBACKLIGHT
|
||||||
//This is where backlight devices can be found in sysfs
|
//This is where backlight devices can be found in sysfs
|
||||||
const char* device_dir(void){return "/sys/class/backlight/";}
|
const char* device_dir(void){return "/sys/class/backlight/";}
|
||||||
|
//name of the program being run so that we print the correct name in the usage
|
||||||
const char* executable_name(void){return "rexbacklight";}
|
const char* executable_name(void){return "rexbacklight";}
|
||||||
|
//location of the restore file in the home directory
|
||||||
const char* restore_file_suffix(void){return "/.config/rexbacklight.json";}
|
const char* restore_file_suffix(void){return "/.config/rexbacklight.json";}
|
||||||
#elif defined(REXLEDCTL)
|
#elif defined(REXLEDCTL)
|
||||||
//This is where led devices can be found in sysfs
|
//This is where led devices can be found in sysfs
|
||||||
@ -53,6 +54,7 @@ const char* restore_file_suffix(void){return "/.config/rexledctl.json";}
|
|||||||
const char* brightness_file(void){return "brightness";}
|
const char* brightness_file(void){return "brightness";}
|
||||||
const char* max_brightness_file(void){return "max_brightness";}
|
const char* max_brightness_file(void){return "max_brightness";}
|
||||||
|
|
||||||
|
|
||||||
//Get a list of led/backlight devices in sysfs
|
//Get a list of led/backlight devices in sysfs
|
||||||
struct string_array get_device_sources(void){
|
struct string_array get_device_sources(void){
|
||||||
DIR* fd;
|
DIR* fd;
|
||||||
@ -77,6 +79,7 @@ struct string_array get_device_sources(void){
|
|||||||
|
|
||||||
for(arr.size = 0;(dir = readdir(fd));){
|
for(arr.size = 0;(dir = readdir(fd));){
|
||||||
int slen;
|
int slen;
|
||||||
|
//ignore '.' and '..'
|
||||||
if(!strncmp(dir->d_name, ".", 1) || !strncmp(dir->d_name, "..", 2)){
|
if(!strncmp(dir->d_name, ".", 1) || !strncmp(dir->d_name, "..", 2)){
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -135,11 +138,13 @@ float get_brightness(const char* file){
|
|||||||
fclose(bright);
|
fclose(bright);
|
||||||
return atof(buff);
|
return atof(buff);
|
||||||
}
|
}
|
||||||
|
//return milliseconds since last boot
|
||||||
double get_time(void){
|
double get_time(void){
|
||||||
struct timespec t;
|
struct timespec t;
|
||||||
clock_gettime(CLOCK_BOOTTIME, &t);
|
clock_gettime(CLOCK_BOOTTIME, &t);
|
||||||
return ((t.tv_sec * 1000.0) + (t.tv_nsec * 0.0000001));
|
return ((t.tv_sec * 1000.0) + (t.tv_nsec * 0.0000001));
|
||||||
}
|
}
|
||||||
|
//sleep thread for milliseconds
|
||||||
void sleep_for(double time){
|
void sleep_for(double time){
|
||||||
DEBUG_PRINT("sleeping for %lf milliseconds\n", time);
|
DEBUG_PRINT("sleeping for %lf milliseconds\n", time);
|
||||||
struct timespec ts;
|
struct timespec ts;
|
||||||
@ -149,7 +154,6 @@ void sleep_for(double time){
|
|||||||
}
|
}
|
||||||
|
|
||||||
//update brightness incrementally over requested millisecond time interval
|
//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, int iv, int fv){
|
||||||
FILE* fd;
|
FILE* fd;
|
||||||
double start, end;
|
double start, end;
|
||||||
@ -198,89 +202,115 @@ void fade_out(struct arg_values* arg, int iv, int fv){
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Write value to device files
|
//Write value to device files
|
||||||
void do_assignment(struct arg_values* arg, const char* device){
|
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 start = get_brightness(brightness_file());
|
||||||
int out = process_op(arg, 0, start, get_brightness(max_brightness_file()));
|
int out = process_op(args, 0, start, get_brightness(max_brightness_file()));
|
||||||
fade_out(arg, start, out);
|
fade_out(args, start, out);
|
||||||
}
|
|
||||||
|
|
||||||
//Run get operation
|
|
||||||
void do_get(const char* device){
|
|
||||||
float curr, max;
|
|
||||||
curr = get_brightness(brightness_file());
|
|
||||||
max = get_brightness(max_brightness_file());
|
|
||||||
if(return_value == RETVAL_INVALID_FILE && (!curr || !max)){
|
|
||||||
fprintf(stdout, "%s", device);
|
|
||||||
}else{
|
|
||||||
fprintf(stdout, "%-25s %.2f\n", device, curr / max * 100);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//Run list operation
|
|
||||||
void do_list(struct string_array* names){
|
|
||||||
for(int i = 0;i < names->size;++i)
|
|
||||||
fprintf(stdout, "%s\n", names->list[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
int individual_device_op(struct arg_values* curr){
|
|
||||||
if(chdir(curr->device)){
|
|
||||||
io_error_2(IO_ERROR_OPEN, IO_ERROR_DIR, device_dir(), curr->device);
|
|
||||||
return RETVAL_INVALID_DIR;
|
|
||||||
}
|
|
||||||
switch(curr->operation){
|
|
||||||
case OP_SET:
|
|
||||||
case OP_INC:
|
|
||||||
case OP_DEC:
|
|
||||||
do_assignment(curr, curr->device);
|
|
||||||
break;
|
|
||||||
case OP_GET:
|
|
||||||
do_get(curr->device);
|
|
||||||
break;
|
|
||||||
case OP_LIST:
|
|
||||||
printf("%s\n", curr->device);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if(chdir(device_dir())){
|
if(chdir(device_dir())){
|
||||||
io_error(IO_ERROR_OPEN, IO_ERROR_DIR, device_dir());
|
io_error(IO_ERROR_OPEN, IO_ERROR_DIR, device_dir());
|
||||||
return RETVAL_INTERNAL_ERROR;
|
return RETVAL_INVALID_DIR;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return return_value;
|
return return_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef ENABLE_RESTORE_FILE
|
//Run get operation
|
||||||
//If devices were specified, this function will run
|
int do_get(struct arg_values* args){
|
||||||
void individual_device_loop(struct arg_values* a){
|
for(;args;args = args->next){
|
||||||
struct arg_values* curr;
|
float curr, max;
|
||||||
RJP_value* root = 0;
|
if(chdir(args->device)){
|
||||||
int try_restore = 1;
|
io_error_2(IO_ERROR_OPEN, IO_ERROR_DIR, device_dir(), args->device);
|
||||||
for(curr = a->next;curr;curr = curr->next){
|
return_value = RETVAL_INVALID_DIR;
|
||||||
if(curr->operation == OP_RESTORE){
|
|
||||||
if(!individual_restore(curr, &root, &try_restore))
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
return_value = individual_device_op(curr);
|
curr = get_brightness(brightness_file());
|
||||||
if(return_value == RETVAL_INTERNAL_ERROR){
|
max = get_brightness(max_brightness_file());
|
||||||
rjp_free_value(root);
|
if(return_value == RETVAL_INVALID_FILE && (!curr || !max)){
|
||||||
return;
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef ENABLE_RESTORE_FILE
|
||||||
|
//convert all restore operations to set operations
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
rjp_free_value(root);
|
rjp_free_value(root);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
//If devices were specified, this function will run
|
#define prep_restore(x)
|
||||||
void individual_device_loop(struct arg_values* a){
|
|
||||||
struct arg_values* curr;
|
|
||||||
int try_restore = 1;
|
|
||||||
for(curr = a->next;curr;curr = curr->next){
|
|
||||||
return_value = individual_device_op(curr);
|
|
||||||
if(return_value == RETVAL_INTERNAL_ERROR)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
//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;
|
||||||
|
}
|
||||||
|
|
||||||
|
//If devices were specified, this function will run
|
||||||
|
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
|
||||||
|
curr = extract_operation(OP_RESTORE, ¤t_op_args, a);
|
||||||
|
prep_restore(current_op_args.next);
|
||||||
|
extract_operation(OP_SET | OP_INC | OP_DEC, curr, a);
|
||||||
|
return_value = do_assignment(current_op_args.next);
|
||||||
|
free_cmd_args(¤t_op_args);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//If a global operation is requested, run this to fill arg with all devices, each with the global operation
|
||||||
void populate_args(struct arg_values* arg, struct string_array* devices){
|
void populate_args(struct arg_values* arg, struct string_array* devices){
|
||||||
struct arg_values* curr = arg;
|
struct arg_values* curr = arg;
|
||||||
for(size_t i = 0;i < devices->size;++i){
|
for(size_t i = 0;i < devices->size;++i){
|
||||||
@ -295,6 +325,8 @@ void populate_args(struct arg_values* arg, struct string_array* devices){
|
|||||||
curr->next = NULL;
|
curr->next = NULL;
|
||||||
arg->num_values = devices->size;
|
arg->num_values = devices->size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int main(int argc, char** argv){
|
int main(int argc, char** argv){
|
||||||
|
|
||||||
struct arg_values args; //A linked list of devices and the requested settings.
|
struct arg_values args; //A linked list of devices and the requested settings.
|
||||||
@ -344,12 +376,10 @@ int main(int argc, char** argv){
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Run selected operation
|
//Run selected operation
|
||||||
if(args.next){
|
if(!args.next){
|
||||||
individual_device_loop(&args);
|
|
||||||
}else{
|
|
||||||
populate_args(&args, &device_names);
|
populate_args(&args, &device_names);
|
||||||
individual_device_loop(&args);
|
|
||||||
}
|
}
|
||||||
|
run_device_operations(&args);
|
||||||
#ifdef ENABLE_RESTORE_FILE
|
#ifdef ENABLE_RESTORE_FILE
|
||||||
save_restore_file(&device_names);
|
save_restore_file(&device_names);
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user