Some cleanup work
This commit is contained in:
parent
dbfa9b9d12
commit
04dcd0684a
@ -38,6 +38,8 @@ else()
|
|||||||
set(enable_RESTORE_FILE "")
|
set(enable_RESTORE_FILE "")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -DREXBACKLIGHT_DEBUG")
|
||||||
|
|
||||||
configure_file(
|
configure_file(
|
||||||
"${INCLUDE_PATH}/config.h.in"
|
"${INCLUDE_PATH}/config.h.in"
|
||||||
"${INCLUDE_PATH}/config.h"
|
"${INCLUDE_PATH}/config.h"
|
||||||
|
|||||||
@ -56,7 +56,10 @@ struct arg_values{
|
|||||||
|
|
||||||
int fade_steps;
|
int fade_steps;
|
||||||
|
|
||||||
unsigned char operation;
|
union{
|
||||||
|
int operation;
|
||||||
|
int num_values;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -19,6 +19,12 @@
|
|||||||
#ifndef REXBACKLIGHT_COMMON_H
|
#ifndef REXBACKLIGHT_COMMON_H
|
||||||
#define REXBACKLIGHT_COMMON_H
|
#define REXBACKLIGHT_COMMON_H
|
||||||
|
|
||||||
|
#ifdef REXBACKLIGHT_DEBUG
|
||||||
|
#define DEBUG_PRINT(s, ...) printf(s, __VA_ARGS__)
|
||||||
|
#else
|
||||||
|
#define DEBUG_PRINT(s, ...)
|
||||||
|
#endif
|
||||||
|
|
||||||
#define RETVAL_INVALID_FILE 1
|
#define RETVAL_INVALID_FILE 1
|
||||||
#define RETVAL_INVALID_DIR 2
|
#define RETVAL_INVALID_DIR 2
|
||||||
#define RETVAL_UNRECOGNIZED_OPTION 3
|
#define RETVAL_UNRECOGNIZED_OPTION 3
|
||||||
@ -45,6 +51,7 @@ struct string_array{
|
|||||||
char** list;
|
char** list;
|
||||||
int size;
|
int size;
|
||||||
};
|
};
|
||||||
|
void free_string_array(struct string_array* s);
|
||||||
|
|
||||||
void mem_error(void);
|
void mem_error(void);
|
||||||
_Noreturn void version(void);
|
_Noreturn void version(void);
|
||||||
|
|||||||
@ -155,6 +155,7 @@ struct arg_values init_arg_values(void){
|
|||||||
struct arg_values process_cmd_args(int argc, char** argv){
|
struct arg_values process_cmd_args(int argc, char** argv){
|
||||||
struct arg_values ret = init_arg_values();
|
struct arg_values ret = init_arg_values();
|
||||||
struct arg_values* curr = &ret;
|
struct arg_values* curr = &ret;
|
||||||
|
int nvals = 0;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
//Skip argv[0]
|
//Skip argv[0]
|
||||||
@ -189,6 +190,7 @@ struct arg_values process_cmd_args(int argc, char** argv){
|
|||||||
*(curr->next) = init_arg_values();
|
*(curr->next) = init_arg_values();
|
||||||
curr = curr->next;
|
curr = curr->next;
|
||||||
curr->device = argv[++i];
|
curr->device = argv[++i];
|
||||||
|
++nvals;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -305,6 +307,8 @@ struct arg_values process_cmd_args(int argc, char** argv){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if(ret.next)
|
||||||
|
ret.num_values = nvals;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
#undef CHECK_OPTION
|
#undef CHECK_OPTION
|
||||||
|
|||||||
@ -36,6 +36,13 @@ void io_error_3(const char* error, const char* type, const char* name, const cha
|
|||||||
fprintf(stderr, "Unable to %s %s '%s%s%s'!\n", error, type, name, name2, name3);
|
fprintf(stderr, "Unable to %s %s '%s%s%s'!\n", error, type, name, name2, name3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Clean up a string array
|
||||||
|
void free_string_array(struct string_array* s){
|
||||||
|
int i;
|
||||||
|
for(i = 0;i < s->size;++i)
|
||||||
|
free(s->list[i]);
|
||||||
|
free(s->list);
|
||||||
|
}
|
||||||
|
|
||||||
void mem_error(void){
|
void mem_error(void){
|
||||||
fprintf(stderr, "Failed to allocate memory! Unable to continue!\n");
|
fprintf(stderr, "Failed to allocate memory! Unable to continue!\n");
|
||||||
|
|||||||
@ -53,14 +53,6 @@ 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";}
|
||||||
|
|
||||||
//Clean up a string array
|
|
||||||
void free_string_array(struct string_array* s){
|
|
||||||
int i;
|
|
||||||
for(i = 0;i < s->size;++i)
|
|
||||||
free(s->list[i]);
|
|
||||||
free(s->list);
|
|
||||||
}
|
|
||||||
|
|
||||||
//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;
|
||||||
@ -83,8 +75,6 @@ struct string_array get_device_sources(void){
|
|||||||
return arr;
|
return arr;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define MEMORY_ERROR() do{mem_error();return_value = RETVAL_MEM_ERROR;free_string_array(&arr);closedir(fd);}while(0)
|
|
||||||
|
|
||||||
for(arr.size = 0;(dir = readdir(fd));){
|
for(arr.size = 0;(dir = readdir(fd));){
|
||||||
int slen;
|
int slen;
|
||||||
if(!strncmp(dir->d_name, ".", 1) || !strncmp(dir->d_name, "..", 2)){
|
if(!strncmp(dir->d_name, ".", 1) || !strncmp(dir->d_name, "..", 2)){
|
||||||
@ -93,13 +83,15 @@ struct string_array get_device_sources(void){
|
|||||||
|
|
||||||
//Resize list if more than 8 led/backlight devices exist (not likely)
|
//Resize list if more than 8 led/backlight devices exist (not likely)
|
||||||
if(arr.size >= list_size){
|
if(arr.size >= list_size){
|
||||||
int j;
|
|
||||||
char** tmp = malloc(sizeof(const char*) * (list_size += 8));
|
char** tmp = malloc(sizeof(const char*) * (list_size += 8));
|
||||||
if(!tmp){
|
if(!tmp){
|
||||||
MEMORY_ERROR();
|
mem_error();
|
||||||
|
return_value = RETVAL_MEM_ERROR;
|
||||||
|
free_string_array(&arr);
|
||||||
|
closedir(fd);
|
||||||
return (struct string_array){0};
|
return (struct string_array){0};
|
||||||
}
|
}
|
||||||
for(j = 0;j < arr.size;++j){
|
for(int j = 0;j < arr.size;++j){
|
||||||
tmp[j] = arr.list[j];
|
tmp[j] = arr.list[j];
|
||||||
}
|
}
|
||||||
free(arr.list);
|
free(arr.list);
|
||||||
@ -109,16 +101,17 @@ struct string_array get_device_sources(void){
|
|||||||
slen = strlen(dir->d_name);
|
slen = strlen(dir->d_name);
|
||||||
arr.list[arr.size] = malloc(slen + 1);
|
arr.list[arr.size] = malloc(slen + 1);
|
||||||
if(!arr.list[arr.size]){
|
if(!arr.list[arr.size]){
|
||||||
MEMORY_ERROR();
|
mem_error();
|
||||||
|
return_value = RETVAL_MEM_ERROR;
|
||||||
|
free_string_array(&arr);
|
||||||
|
closedir(fd);
|
||||||
return (struct string_array){0};
|
return (struct string_array){0};
|
||||||
}
|
}
|
||||||
strcpy(arr.list[arr.size], dir->d_name);
|
strncpy(arr.list[arr.size], dir->d_name, slen);
|
||||||
arr.list[arr.size][slen] = 0;
|
arr.list[arr.size][slen] = 0;
|
||||||
++arr.size;
|
++arr.size;
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef MEMORY_ERROR
|
|
||||||
|
|
||||||
closedir(fd);
|
closedir(fd);
|
||||||
return arr;
|
return arr;
|
||||||
}
|
}
|
||||||
@ -142,42 +135,52 @@ float get_brightness(const char* file){
|
|||||||
fclose(bright);
|
fclose(bright);
|
||||||
return atof(buff);
|
return atof(buff);
|
||||||
}
|
}
|
||||||
|
double get_time(void){
|
||||||
|
struct timespec t;
|
||||||
|
clock_gettime(CLOCK_BOOTTIME, &t);
|
||||||
|
return ((t.tv_sec * 1000.0) + (t.tv_nsec * 0.0000001));
|
||||||
|
}
|
||||||
|
void sleep_for(double time){
|
||||||
|
DEBUG_PRINT("sleeping for %lf milliseconds\n", time);
|
||||||
|
struct timespec ts;
|
||||||
|
ts.tv_sec = (long)(time*0.0001);
|
||||||
|
ts.tv_nsec = ((time) - ts.tv_sec*1000) * 1000*1000;
|
||||||
|
nanosleep(&ts, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
//update brightness incrementally over requested millisecond time interval
|
//update brightness incrementally over requested millisecond time interval
|
||||||
void fade_out(const char* device_name, int iv, int fv, int ms_duration, int steps){
|
|
||||||
|
void fade_out(struct arg_values* arg, int iv, int fv){
|
||||||
FILE* fd;
|
FILE* fd;
|
||||||
struct timeval start, end;
|
double start, end;
|
||||||
double tdelta = 0; //amount of time that has passed in ms
|
double tdelta = 0; //amount of time that has passed in ms
|
||||||
float value = iv; //current value to write to file
|
float value = iv; //current value to write to file
|
||||||
int step_delta = ms_duration / steps;
|
double step_delta = (double)arg->fade_duration / arg->fade_steps;
|
||||||
int step_inc = step_delta;
|
double step_inc = step_delta;
|
||||||
float brdelta = (float)(fv - iv) / steps; //amount brightness needs to change per iteration
|
float brdelta = (float)(fv - iv) / arg->fade_steps; //amount brightness needs to change per iteration
|
||||||
|
|
||||||
while(ms_duration > tdelta){
|
while(arg->fade_duration > tdelta){
|
||||||
//write
|
//write
|
||||||
gettimeofday(&start, NULL);
|
start = get_time();
|
||||||
fd = fopen(brightness_file(), "w+");
|
fd = fopen(brightness_file(), "w+");
|
||||||
if(!fd){
|
if(!fd){
|
||||||
io_error_3(IO_ERROR_OPEN, IO_ERROR_FILE, device_dir(), device_name, brightness_file());
|
io_error_3(IO_ERROR_OPEN, IO_ERROR_FILE, device_dir(), arg->device, brightness_file());
|
||||||
return_value = RETVAL_INVALID_FILE;
|
return_value = RETVAL_INVALID_FILE;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
fprintf(fd, "%d", (int)value);
|
fprintf(fd, "%d", (int)value);
|
||||||
fclose(fd);
|
fclose(fd);
|
||||||
gettimeofday(&end, NULL);
|
end = get_time();
|
||||||
|
|
||||||
//calc time delta
|
//calc time delta
|
||||||
tdelta += (((end.tv_sec * 1000.0) + (end.tv_usec / 1000.0)) - ((start.tv_sec * 1000.0) + (start.tv_usec / 1000.0)));
|
tdelta += end - start;
|
||||||
|
|
||||||
//calc next value to write
|
//calc next value to write
|
||||||
value += brdelta;
|
value += brdelta;
|
||||||
|
|
||||||
//waste excess time until next step
|
//waste excess time until next step
|
||||||
if(step_delta > tdelta){
|
if(step_delta > tdelta){
|
||||||
struct timespec ts;
|
sleep_for(step_delta - tdelta);
|
||||||
ts.tv_sec = (long)((step_delta - tdelta)/1000);
|
|
||||||
ts.tv_nsec = ((step_delta - tdelta) - ts.tv_sec*1000) * 1000*1000;
|
|
||||||
nanosleep(&ts, NULL);
|
|
||||||
tdelta = step_delta;
|
tdelta = step_delta;
|
||||||
}
|
}
|
||||||
//calc end of next step
|
//calc end of next step
|
||||||
@ -185,7 +188,7 @@ void fade_out(const char* device_name, int iv, int fv, int ms_duration, int step
|
|||||||
}
|
}
|
||||||
fd = fopen(brightness_file(), "w+");
|
fd = fopen(brightness_file(), "w+");
|
||||||
if(!fd){
|
if(!fd){
|
||||||
io_error_3(IO_ERROR_OPEN, IO_ERROR_FILE, device_dir(), device_name, brightness_file());
|
io_error_3(IO_ERROR_OPEN, IO_ERROR_FILE, device_dir(), arg->device, brightness_file());
|
||||||
return_value = RETVAL_INVALID_FILE;
|
return_value = RETVAL_INVALID_FILE;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -198,7 +201,7 @@ void fade_out(const char* device_name, int iv, int fv, int ms_duration, int step
|
|||||||
void do_assignment(struct arg_values* arg, const char* device){
|
void do_assignment(struct arg_values* arg, const char* device){
|
||||||
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(arg, 0, start, get_brightness(max_brightness_file()));
|
||||||
fade_out(device, start, out, arg->fade_duration, arg->fade_steps);
|
fade_out(arg, start, out);
|
||||||
}
|
}
|
||||||
|
|
||||||
//Run get operation
|
//Run get operation
|
||||||
@ -215,8 +218,7 @@ void do_get(const char* device){
|
|||||||
|
|
||||||
//Run list operation
|
//Run list operation
|
||||||
void do_list(struct string_array* names){
|
void do_list(struct string_array* names){
|
||||||
int i;
|
for(int i = 0;i < names->size;++i)
|
||||||
for(i = 0;i < names->size;++i)
|
|
||||||
fprintf(stdout, "%s\n", names->list[i]);
|
fprintf(stdout, "%s\n", names->list[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -234,6 +236,9 @@ int individual_device_op(struct arg_values* curr){
|
|||||||
case OP_GET:
|
case OP_GET:
|
||||||
do_get(curr->device);
|
do_get(curr->device);
|
||||||
break;
|
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());
|
||||||
@ -275,64 +280,26 @@ void individual_device_loop(struct arg_values* a){
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
//If no devices were specified, this function will run
|
|
||||||
void all_device_loop(struct string_array* device_names, struct arg_values* args){
|
|
||||||
int i;
|
|
||||||
switch(args->operation){
|
|
||||||
case OP_SET:
|
|
||||||
case OP_INC:
|
|
||||||
case OP_DEC:
|
|
||||||
for(i = 0;i < device_names->size;++i){
|
|
||||||
if(chdir(device_names->list[i])){
|
|
||||||
io_error_2(IO_ERROR_OPEN, IO_ERROR_DIR, device_dir(), device_names->list[i]);
|
|
||||||
return_value = RETVAL_INVALID_DIR;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
do_assignment(args, device_names->list[i]);
|
|
||||||
if(chdir(device_dir())){
|
|
||||||
io_error(IO_ERROR_OPEN, IO_ERROR_DIR, device_dir());
|
|
||||||
return_value = RETVAL_INVALID_DIR;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#ifdef ENABLE_RESTORE_FILE
|
|
||||||
save_restore_file(device_names);
|
|
||||||
#endif
|
|
||||||
break;
|
|
||||||
case OP_LIST:
|
|
||||||
do_list(device_names);
|
|
||||||
break;
|
|
||||||
case OP_GET:
|
|
||||||
for(i = 0;i < device_names->size;++i){
|
|
||||||
if(chdir(device_names->list[i])){
|
|
||||||
io_error_2(IO_ERROR_OPEN, IO_ERROR_DIR, device_dir(), device_names->list[i]);
|
|
||||||
return_value = RETVAL_INVALID_DIR;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
do_get(device_names->list[i]);
|
|
||||||
if(chdir(device_dir())){
|
|
||||||
io_error(IO_ERROR_OPEN, IO_ERROR_DIR, device_dir());
|
|
||||||
return_value = RETVAL_INVALID_DIR;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
#ifdef ENABLE_RESTORE_FILE
|
|
||||||
case OP_RESTORE:;
|
|
||||||
all_restore();
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
default:
|
|
||||||
fprintf(stderr, "Internal processing error!\n");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
void populate_args(struct arg_values* arg, struct string_array* devices){
|
||||||
|
struct arg_values* curr = arg;
|
||||||
|
for(size_t i = 0;i < devices->size;++i){
|
||||||
|
curr->next = malloc(sizeof(struct arg_values));
|
||||||
|
curr->next->device = devices->list[i];
|
||||||
|
curr->next->delta = arg->delta;
|
||||||
|
curr->next->fade_duration = arg->fade_duration;
|
||||||
|
curr->next->fade_steps = arg->fade_steps;
|
||||||
|
curr->next->operation = arg->operation;
|
||||||
|
curr = curr->next;
|
||||||
|
}
|
||||||
|
curr->next = NULL;
|
||||||
|
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.
|
||||||
struct string_array device_names; //List of all led/backlight devices in sysfs.
|
struct string_array device_names; //List of all led/backlight devices in sysfs.
|
||||||
struct arg_values* curr;
|
|
||||||
args = process_cmd_args(argc, argv);
|
args = process_cmd_args(argc, argv);
|
||||||
if(args.operation == OP_USAGE){
|
if(args.operation == OP_USAGE){
|
||||||
usage(return_value);
|
usage(return_value);
|
||||||
@ -342,34 +309,28 @@ int main(int argc, char** argv){
|
|||||||
|
|
||||||
device_names = get_device_sources();
|
device_names = get_device_sources();
|
||||||
|
|
||||||
//Macro for easy memory cleaning
|
|
||||||
#define CLEANUP() do{free_string_array(&device_names);free_cmd_args(&args);}while(0)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//If there are no led/backlights, we can't do anything
|
//If there are no led/backlights, we can't do anything
|
||||||
if(device_names.size == 0){
|
if(device_names.size == 0){
|
||||||
#ifdef REXBACKLIGHT
|
#ifdef REXBACKLIGHT
|
||||||
fprintf(stderr, "No backlights devices found!\n");
|
fprintf(stderr, "No backlights devices found!\n");
|
||||||
#elif defined(REXLEDCTL)
|
#elif defined(REXLEDCTL)
|
||||||
fprintf(stderr, "No led devices found!\n");
|
fprintf(stderr, "No led devices found!\n");
|
||||||
#else
|
|
||||||
#error "UNDEFINED PROGRAM NAME!"
|
|
||||||
#endif
|
#endif
|
||||||
CLEANUP();
|
free_string_array(&device_names);
|
||||||
|
free_cmd_args(&args);
|
||||||
return RETVAL_INVALID_DEVICE;
|
return RETVAL_INVALID_DEVICE;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Make sure all explicit devices actually exist
|
//Make sure all explicit devices actually exist
|
||||||
for(curr = args.next;curr;curr = curr->next){
|
for(struct arg_values* curr = args.next;curr;curr = curr->next){
|
||||||
int i;
|
for(int i = 0;i < device_names.size;++i){
|
||||||
for(i = 0;i < device_names.size;++i){
|
|
||||||
if(!strcmp(curr->device, device_names.list[i])){
|
if(!strcmp(curr->device, device_names.list[i])){
|
||||||
goto continue_outer;
|
goto continue_outer;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fprintf(stderr, "No such device '%s'\n", curr->device);
|
fprintf(stderr, "No such device '%s'\n", curr->device);
|
||||||
CLEANUP();
|
free_string_array(&device_names);
|
||||||
|
free_cmd_args(&args);
|
||||||
return RETVAL_INVALID_DEVICE;
|
return RETVAL_INVALID_DEVICE;
|
||||||
continue_outer:;
|
continue_outer:;
|
||||||
}
|
}
|
||||||
@ -377,21 +338,23 @@ int main(int argc, char** argv){
|
|||||||
//Change to the base directory for all sysfs leds/backlights
|
//Change to the base directory for all sysfs leds/backlights
|
||||||
if(chdir(device_dir())){
|
if(chdir(device_dir())){
|
||||||
io_error(IO_ERROR_READ, IO_ERROR_DIR, device_dir());
|
io_error(IO_ERROR_READ, IO_ERROR_DIR, device_dir());
|
||||||
CLEANUP();
|
free_string_array(&device_names);
|
||||||
|
free_cmd_args(&args);
|
||||||
return RETVAL_INVALID_DIR;
|
return RETVAL_INVALID_DIR;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Run selected operation
|
//Run selected operation
|
||||||
if(args.next){
|
if(args.next){
|
||||||
individual_device_loop(&args);
|
individual_device_loop(&args);
|
||||||
|
}else{
|
||||||
|
populate_args(&args, &device_names);
|
||||||
|
individual_device_loop(&args);
|
||||||
|
}
|
||||||
#ifdef ENABLE_RESTORE_FILE
|
#ifdef ENABLE_RESTORE_FILE
|
||||||
save_restore_file(&device_names);
|
save_restore_file(&device_names);
|
||||||
#endif
|
#endif
|
||||||
}else{
|
|
||||||
all_device_loop(&device_names, &args);
|
|
||||||
}
|
|
||||||
|
|
||||||
CLEANUP();
|
free_string_array(&device_names);
|
||||||
|
free_cmd_args(&args);
|
||||||
return return_value;
|
return return_value;
|
||||||
}
|
}
|
||||||
#undef CLEANUP
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user