11 Commits
v1.3.1 ... v1.5

Author SHA1 Message Date
rexy712
f868074f0c please 2019-01-14 16:17:57 -08:00
rexy712
2fdd9fa13b fixed typo 2019-01-14 16:11:53 -08:00
rexy712
40eec1fb23 hope this fixes it... 2019-01-14 16:07:33 -08:00
rexy712
42f93ba026 really fixed version this time 2019-01-14 16:04:09 -08:00
rexy712
44ddaae28d fixed version output 2019-01-14 16:01:49 -08:00
rexy712
5986fa8133 Fixed version number 2019-01-14 15:55:33 -08:00
rexy712
479e7c1f17 Removed the cool git versioning thing because it won't work when distributed 2019-01-14 15:54:47 -08:00
rexy712
2dd52c32b7 Fixed memory leak when restore file is disabled and prevent restore file parsing when no write is performed 2018-12-16 15:42:22 -08:00
rexy712
87b7dd2503 Added option to not write to restore file and fixed a lot of restore file issues 2018-12-16 14:27:58 -08:00
rexy712
3c2e3f35a0 Version now includes dirty status on exact version tags too 2018-12-16 07:18:31 -08:00
rexy712
00062612f5 Cleaned up option management in cmd.c and moved a restore operation from rexbacklight.c to restore.c 2018-12-16 06:56:18 -08:00
10 changed files with 216 additions and 206 deletions

View File

@@ -23,9 +23,7 @@ if(PYTHONINTERP_FOUND)
add_custom_command( add_custom_command(
OUTPUT ${GIT_VERSION_TMP_FILE} OUTPUT ${GIT_VERSION_TMP_FILE}
COMMAND ${CMAKE_COMMAND} -E echo "//File generated by CMake. Do not edit!" > ${GIT_VERSION_TMP_FILE} COMMAND ${CMAKE_COMMAND} -E echo "//File generated by CMake. Do not edit!" > ${GIT_VERSION_TMP_FILE}
COMMAND ${PYTHON_EXECUTABLE} ${SCRIPT_DIR}/git_branch_name.py >> ${GIT_VERSION_TMP_FILE} COMMAND ${CMAKE_COMMAND} -E echo "#define GIT_TAG_NAME \"v1.5\"" > ${GIT_VERSION_TMP_FILE}
COMMAND ${PYTHON_EXECUTABLE} ${SCRIPT_DIR}/git_commit_hash.py >> ${GIT_VERSION_TMP_FILE}
COMMAND ${PYTHON_EXECUTABLE} ${SCRIPT_DIR}/git_tag_name.py >> ${GIT_VERSION_TMP_FILE}
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${GIT_VERSION_TMP_FILE} ${GIT_VERSION_FILE} COMMAND ${CMAKE_COMMAND} -E copy_if_different ${GIT_VERSION_TMP_FILE} ${GIT_VERSION_FILE}
COMMAND ${CMAKE_COMMAND} -E remove ${GIT_VERSION_TMP_FILE} COMMAND ${CMAKE_COMMAND} -E remove ${GIT_VERSION_TMP_FILE}
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
@@ -36,9 +34,7 @@ elseif(UNIX)
add_custom_command( add_custom_command(
OUTPUT ${GIT_VERSION_TMP_FILE} OUTPUT ${GIT_VERSION_TMP_FILE}
COMMAND ${CMAKE_COMMAND} -E echo "//File generated by CMake. Do not edit!" > ${GIT_VERSION_TMP_FILE} COMMAND ${CMAKE_COMMAND} -E echo "//File generated by CMake. Do not edit!" > ${GIT_VERSION_TMP_FILE}
COMMAND ${SCRIPT_DIR}/git_branch_name.sh >> ${GIT_VERSION_TMP_FILE} COMMAND ${CMAKE_COMMAND} -E echo "#define GIT_TAG_NAME \"v1.5\"" > ${GIT_VERSION_TMP_FILE}
COMMAND ${SCRIPT_DIR}/git_commit_hash.sh >> ${GIT_VERSION_TMP_FILE}
COMMAND ${SCRIPT_DIR}/git_tag_name.sh >> ${GIT_VERSION_TMP_FILE}
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${GIT_VERSION_TMP_FILE} ${GIT_VERSION_FILE} COMMAND ${CMAKE_COMMAND} -E copy_if_different ${GIT_VERSION_TMP_FILE} ${GIT_VERSION_FILE}
COMMAND ${CMAKE_COMMAND} -E remove ${GIT_VERSION_TMP_FILE} COMMAND ${CMAKE_COMMAND} -E remove ${GIT_VERSION_TMP_FILE}
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
@@ -82,11 +78,11 @@ if(BUILD_REXLEDCTL)
add_executable (rexledctl src/rexbacklight.c) add_executable (rexledctl src/rexbacklight.c)
add_dependencies(rexledctl common_srcs) #force common_srcs to be built first add_dependencies(rexledctl common_srcs) #force common_srcs to be built first
target_compile_definitions(rexledctl PRIVATE REXLEDCTL) #define REXLEDCTL in C files target_compile_definitions(rexledctl PRIVATE REXLEDCTL) #define REXLEDCTL in C files
target_link_libraries(rexledctl PRIVATE $<TARGET_OBJECTS:common_srcs>) #link with the common_srcs "library"
if(ENABLE_RESTORE_FILE) if(ENABLE_RESTORE_FILE)
target_link_libraries(rexledctl PRIVATE "${RJP_LIB}") #link with rjp target_link_libraries(rexledctl PRIVATE "${RJP_LIB}") #link with rjp
target_include_directories(rexledctl PUBLIC "${RJP_HEADER_DIR}") #include rjp.h directory target_include_directories(rexledctl PUBLIC "${RJP_HEADER_DIR}") #include rjp.h directory
endif() endif()
target_link_libraries(rexledctl PRIVATE $<TARGET_OBJECTS:common_srcs>) #link with the common_srcs "library"
install(TARGETS rexledctl RUNTIME DESTINATION bin) install(TARGETS rexledctl RUNTIME DESTINATION bin)
if(INSTALL_UDEV_LED_RULE) if(INSTALL_UDEV_LED_RULE)
install(FILES ${CMAKE_SOURCE_DIR}/rules/91-leds.rules DESTINATION ${UDEV_DIR}) install(FILES ${CMAKE_SOURCE_DIR}/rules/91-leds.rules DESTINATION ${UDEV_DIR})
@@ -95,13 +91,13 @@ endif()
#build backlight control program #build backlight control program
if(BUILD_REXBACKLIGHT) if(BUILD_REXBACKLIGHT)
add_executable (rexbacklight src/rexbacklight.c) add_executable (rexbacklight src/rexbacklight.c)
add_dependencies(rexledctl common_srcs) add_dependencies(rexbacklight common_srcs)
target_compile_definitions(rexbacklight PRIVATE REXBACKLIGHT) target_compile_definitions(rexbacklight PRIVATE REXBACKLIGHT)
target_link_libraries(rexbacklight PRIVATE $<TARGET_OBJECTS:common_srcs>)
if(ENABLE_RESTORE_FILE) if(ENABLE_RESTORE_FILE)
target_link_libraries(rexbacklight PRIVATE "${RJP_LIB}") target_link_libraries(rexbacklight PRIVATE "${RJP_LIB}")
target_include_directories(rexbacklight PUBLIC "${RJP_HEADER_DIR}") target_include_directories(rexbacklight PUBLIC "${RJP_HEADER_DIR}")
endif() endif()
target_link_libraries(rexbacklight PRIVATE $<TARGET_OBJECTS:common_srcs>)
install(TARGETS rexbacklight RUNTIME DESTINATION bin) install(TARGETS rexbacklight RUNTIME DESTINATION bin)
if(INSTALL_UDEV_BACKLIGHT_RULE) if(INSTALL_UDEV_BACKLIGHT_RULE)
install(FILES ${CMAKE_SOURCE_DIR}/rules/91-backlight.rules DESTINATION ${UDEV_DIR}) install(FILES ${CMAKE_SOURCE_DIR}/rules/91-backlight.rules DESTINATION ${UDEV_DIR})

View File

@@ -29,6 +29,9 @@
#define OP_VERSION 254 #define OP_VERSION 254
#define OP_USAGE 255 #define OP_USAGE 255
#define ARG_FLAG_NONE 0
#define ARG_FLAG_NO_SAVE 1
struct cmd_arg{ struct cmd_arg{
const char* lopt; const char* lopt;
const char* sopt; const char* sopt;
@@ -48,7 +51,11 @@ struct arg_values{
//NULL means all devices //NULL means all devices
const char* device; 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; float delta;
//How many seconds to transition //How many seconds to transition
@@ -60,6 +67,7 @@ struct arg_values{
int operation; int operation;
int num_values; int num_values;
}; };
int flags;
}; };

View File

@@ -22,7 +22,11 @@
#include "version.h" #include "version.h"
#ifdef GIT_TAG_NAME #ifdef GIT_TAG_NAME
#define REXBACKLIGHT_VERSION GIT_TAG_NAME #ifdef GIT_DIRTY
#define REXBACKLIGHT_VERSION GIT_TAG_NAME "-dirty"
#else
#define REXBACKLIGHT_VERSION GIT_TAG_NAME
#endif
#else #else
#define REXBACKLIGHT_VERSION GIT_BRANCH_NAME "-" GIT_COMMIT_HASH #define REXBACKLIGHT_VERSION GIT_BRANCH_NAME "-" GIT_COMMIT_HASH
#endif #endif

View File

@@ -24,8 +24,9 @@
#include "common.h" #include "common.h"
#include "cmd.h" #include "cmd.h"
void save_restore_file(struct string_array* devices); void save_restore_file(struct string_array* devices, struct arg_values* args);
int restore_to_delta(struct arg_values* curr, RJP_value** root, int* try_restore); 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* 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);

View File

@@ -6,3 +6,5 @@ output = subprocess.run(['git', 'describe', "--always", "--dirty", "--abbrev", "
if output: if output:
print("#define GIT_COMMIT_HASH " + '"' + output + '"') print("#define GIT_COMMIT_HASH " + '"' + output + '"')
if output.find("dirty") != -1:
print("#define GIT_DIRTY")

View File

@@ -4,4 +4,7 @@ output="$(git describe --always --dirty --abbrev --match="NeVeRmAtCh")"
if test -n output;then if test -n output;then
echo "#define GIT_COMMIT_HASH \"$output\"" echo "#define GIT_COMMIT_HASH \"$output\""
if grep -q "dirty" <<< "$output";then
echo "#define GIT_DIRTY"
fi
fi fi

View File

@@ -58,6 +58,9 @@
#define RESTORE_LONG_OPT "--restore" #define RESTORE_LONG_OPT "--restore"
#define RESTORE_SHORT_OPT "-R" #define RESTORE_SHORT_OPT "-R"
#define RESTORE_XBACK_OPT NO_OPT #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 DEVICE_DESC "select which device to control"
#define FADE_DESC "change brightness over time interval" #define FADE_DESC "change brightness over time interval"
@@ -70,8 +73,9 @@
#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 device values" #define RESTORE_DESC "reassign previously saved device values"
#define NO_SAVE_DESC "do not write any data to the restore file"
int strcmp_handle_null(const char* one, const char* two){ static inline int strcmp_handle_null(const char* one, const char* two){
if(!one) if(!one)
return 1; return 1;
if(!two) if(!two)
@@ -79,48 +83,37 @@ int strcmp_handle_null(const char* one, const char* two){
return strcmp(one, two); return strcmp(one, two);
} }
#define CHECK_SHORT_OPTION(opt, arg) (!strcmp(opt##_SHORT_OPT, arg)) #define CHECK_SHORT_OPTION(opt, arg) (!strcmp_handle_null(opt##_SHORT_OPT, arg))
#define CHECK_LONG_OPTION(opt, arg) (!strcmp(opt##_LONG_OPT, arg)) #define CHECK_LONG_OPTION(opt, arg) (!strcmp_handle_null(opt##_LONG_OPT, arg))
#define CHECK_XBACK_OPTION(opt, arg) (!strcmp(opt##_XBACK_OPT, arg)) #define CHECK_XBACK_OPTION(opt, arg) (!strcmp_handle_null(opt##_XBACK_OPT, arg))
#ifdef XBACKLIGHT_COMPAT_OPTIONS #ifdef XBACKLIGHT_COMPAT_OPTIONS
#define OPTION(x) {x##_LONG_OPT, x##_SHORT_OPT, x##_XBACK_OPT, x##_DESC}
#define CHECK_OPTION(opt, arg) (!strcmp_handle_null(opt##_LONG_OPT, arg) || !strcmp_handle_null(opt##_SHORT_OPT, arg) || !strcmp_handle_null(opt##_XBACK_OPT, arg)) #define CHECK_OPTION(opt, arg) (CHECK_LONG_OPTION(opt, arg) || CHECK_SHORT_OPTION(opt, arg) || CHECK_XBACK_OPTION(opt, arg))
struct cmd_arg rexbacklight_args[] = {
{DEVICE_LONG_OPT, DEVICE_SHORT_OPT, DEVICE_XBACK_OPT, DEVICE_DESC},
{NO_OPT, NO_OPT, SET_XBACK_OPT, SET_DESC},
{NO_OPT, NO_OPT, INC_XBACK_OPT, INC_DESC},
{NO_OPT, NO_OPT, DEC_XBACK_OPT, DEC_DESC},
{FADE_LONG_OPT, FADE_SHORT_OPT, FADE_XBACK_OPT, FADE_DESC},
{STEPS_LONG_OPT, STEPS_SHORT_OPT, STEPS_XBACK_OPT, STEPS_DESC},
{GET_LONG_OPT, GET_SHORT_OPT, GET_XBACK_OPT, GET_DESC},
{LIST_LONG_OPT, LIST_SHORT_OPT, LIST_XBACK_OPT, LIST_DESC},
#ifdef ENABLE_RESTORE_FILE
{RESTORE_LONG_OPT, RESTORE_SHORT_OPT, RESTORE_XBACK_OPT, RESTORE_DESC},
#endif
{HELP_LONG_OPT, HELP_SHORT_OPT, HELP_XBACK_OPT, HELP_DESC},
{VERSION_LONG_OPT, NO_OPT, VERSION_XBACK_OPT, VERSION_DESC}
};
#else //XBACKLIGHT_COMPAT_OPTIONS #else //XBACKLIGHT_COMPAT_OPTIONS
#define OPTION(x) {x##_LONG_OPT, x##_SHORT_OPT, x##_DESC}
#define CHECK_OPTION(opt, arg) (!strcmp_handle_null(opt##_LONG_OPT, arg) || !strcmp_handle_null(opt##_SHORT_OPT, arg)) #define CHECK_OPTION(opt, arg) (CHECK_LONG_OPTION(opt, arg) || CHECK_SHORT_OPTION(opt, arg))
struct cmd_arg rexbacklight_args[] = {
{DEVICE_LONG_OPT, DEVICE_SHORT_OPT, DEVICE_DESC},
{FADE_LONG_OPT, FADE_SHORT_OPT, FADE_DESC},
{STEPS_LONG_OPT, STEPS_SHORT_OPT, STEPS_DESC},
{GET_LONG_OPT, GET_SHORT_OPT, GET_DESC},
{LIST_LONG_OPT, LIST_SHORT_OPT, LIST_DESC},
#ifdef ENABLE_RESTORE_FILE
{RESTORE_LONG_OPT, RESTORE_SHORT_OPT, RESTORE_DESC},
#endif
{HELP_LONG_OPT, HELP_SHORT_OPT, HELP_DESC},
{VERSION_LONG_OPT, NO_OPT, VERSION_DESC}
};
#endif //XBACKLIGHT_COMPAT_OPTIONS #endif //XBACKLIGHT_COMPAT_OPTIONS
int rexbacklight_args_length = sizeof(rexbacklight_args) / sizeof(rexbacklight_args[0]); struct cmd_arg rexbacklight_args[] = {
OPTION(DEVICE),
OPTION(SET),
OPTION(INC),
OPTION(DEC),
OPTION(FADE),
OPTION(STEPS),
OPTION(GET),
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 //Clean up a cmd_arg struct
void free_cmd_args(struct arg_values* a){ void free_cmd_args(struct arg_values* a){
if(!a->next) if(!a->next)
@@ -147,7 +140,7 @@ void free_cmd_args(struct arg_values* a){
}while(0); }while(0);
struct arg_values init_arg_values(void){ 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 //Convert command line arguments to flags
@@ -162,7 +155,7 @@ struct arg_values process_cmd_args(int argc, char** argv){
//Check for switches //Check for switches
if(CHECK_OPTION(GET, argv[i])){ if(CHECK_OPTION(GET, argv[i])){
curr->operation |= OP_GET; curr->operation = OP_GET;
continue; continue;
}else if(CHECK_OPTION(FADE, argv[i])){ }else if(CHECK_OPTION(FADE, argv[i])){
@@ -203,14 +196,14 @@ struct arg_values process_cmd_args(int argc, char** argv){
} }
else if(CHECK_OPTION(LIST, argv[i])){ else if(CHECK_OPTION(LIST, argv[i])){
free_cmd_args(&ret); curr->operation = OP_LIST;
ret.operation = OP_LIST;
ret.next = NULL;
return ret;
} }
#ifdef ENABLE_RESTORE_FILE #ifdef ENABLE_RESTORE_FILE
else if(CHECK_OPTION(RESTORE, argv[i])){ 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 #endif
else if(!strcmp(argv[i], "max")){ else if(!strcmp(argv[i], "max")){
@@ -302,7 +295,9 @@ struct arg_values process_cmd_args(int argc, char** argv){
curr->operation = ret.operation; curr->operation = ret.operation;
if(!curr->delta) if(!curr->delta)
curr->delta = ret.delta; curr->delta = ret.delta;
}
if(curr->flags == ARG_FLAG_NONE){
curr->flags = ret.flags;
} }
} }
} }
@@ -312,6 +307,7 @@ struct arg_values process_cmd_args(int argc, char** argv){
} }
#undef CHECK_OPTION #undef CHECK_OPTION
#undef UNRECOGNIZED_OPTION #undef UNRECOGNIZED_OPTION
#undef OPTION
//Process an operation //Process an operation
int process_op(struct arg_values* arg, float min, float current, float max){ int process_op(struct arg_values* arg, float min, float current, float max){

View File

@@ -35,6 +35,9 @@ void io_error_2(const char* error, const char* type, const char* name, const cha
void io_error_3(const char* error, const char* type, const char* name, const char* name2, const char* name3){ void io_error_3(const char* error, const char* type, const char* name, const char* name2, const char* name3){
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);
} }
void mem_error(void){
fprintf(stderr, "Failed to allocate memory! Unable to continue!\n");
}
//Clean up a string array //Clean up a string array
void free_string_array(struct string_array* s){ void free_string_array(struct string_array* s){
@@ -44,10 +47,6 @@ void free_string_array(struct string_array* s){
free(s->list); free(s->list);
} }
void mem_error(void){
fprintf(stderr, "Failed to allocate memory! Unable to continue!\n");
}
_Noreturn void version(void){ _Noreturn void version(void){
printf("%s version %s\n", executable_name(), REXBACKLIGHT_VERSION); printf("%s version %s\n", executable_name(), REXBACKLIGHT_VERSION);
exit(return_value); exit(return_value);
@@ -76,11 +75,15 @@ _Noreturn void usage(int exit_val){
if(rexbacklight_args[i].xopt){ if(rexbacklight_args[i].xopt){
if(printed) if(printed)
printf("|"); printf("|");
else
printed = 1;
printf("%s", rexbacklight_args[i].xopt); printf("%s", rexbacklight_args[i].xopt);
} }
#endif //XBACKLIGHT_COMPAT_OPTIONS #endif //XBACKLIGHT_COMPAT_OPTIONS
printf("\n"); if(printed){
printf(" %s\n", rexbacklight_args[i].desc); printf("\n");
printf(" %s\n", rexbacklight_args[i].desc);
}
} }
printf("\n"); printf("\n");
printf("Arguments:\n"); printf("Arguments:\n");

View File

@@ -66,7 +66,6 @@ RJP_value* read_restore_file(const char* file){
int i; int i;
FILE* fp = fopen(file, "r"); FILE* fp = fopen(file, "r");
if(!fp){ if(!fp){
fprintf(stderr, "Could not restore! No restore file found!\n");
return NULL; return NULL;
} }
@@ -83,6 +82,16 @@ RJP_value* read_restore_file(const char* file){
return root; 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){ 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)){ for(RJP_value* curr = rjp_get_member(root);curr;curr = rjp_next_member(curr)){
if(!strcmp(rjp_member_name(curr), name)){ 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 //convert a restoration operation to a set operation
int restore_to_delta(struct arg_values* curr, RJP_value** root, int* try_restore){ int restore_to_delta(struct arg_values* curr){
if(!*root && *try_restore){ RJP_value* root = restore_file_handle();
char* tmp = restore_file(); if(!root){
*root = read_restore_file(tmp); fprintf(stderr, "Could not restore! No restore file found!\n");
free(tmp); return 0;
if(!*root){
*try_restore = 0;
return 0;
}
} }
RJP_value* match = find_matching_json_device(curr->device, *root); RJP_value* match = find_matching_json_device(curr->device, root);
if(!match){ if(!match){
fprintf(stderr, "No matching device '%s' in restore file!\n", curr->device); fprintf(stderr, "No matching device '%s' in restore file!\n", curr->device);
return 0; return 0;
@@ -112,36 +117,39 @@ int restore_to_delta(struct arg_values* curr, RJP_value** root, int* try_restore
curr->delta = rjp_value_dfloat(match); curr->delta = rjp_value_dfloat(match);
return 1; return 1;
} }
void prep_restore(struct arg_values* a){
for(struct arg_values* curr = a;curr;curr = curr->next){
restore_to_delta(curr);
}
}
void save_restore_file(struct string_array* devices){ void save_restore_file(struct string_array* devices, struct arg_values* args){
RJP_value* root = rjp_init_json(); RJP_value* rf = restore_file_handle();
for(size_t i = 0;i < devices->size;++i){ if(!rf)
if(chdir(devices->list[i])){ rf = rjp_init_json();
io_error_2(IO_ERROR_OPEN, IO_ERROR_DIR, device_dir(), devices->list[i]); for(RJP_value* mem = rjp_get_member(rf);mem;mem = rjp_next_member(mem)){
return_value = RETVAL_INVALID_DIR; for(struct arg_values* curr = args->next, *prev = args;curr;prev = curr, curr = curr->next){
continue; if(curr->operation != OP_SET || curr->flags & ARG_FLAG_NO_SAVE){
} prev->next = curr->next;
size_t esc_name_len = rjp_escape_strlen(devices->list[i]); free(curr);
char* esc_str = rjp_alloc(esc_name_len + 1); curr = prev;
rjp_escape_strcpy(esc_str, devices->list[i]); continue;
}
float curr = get_brightness(brightness_file()); if(!strcmp(rjp_member_name(mem), curr->device)){
float max = get_brightness(max_brightness_file()); rjp_set_value(mem, rjp_dfloat(curr->delta));
if(return_value == RETVAL_INVALID_FILE && (!curr || !max)){ prev->next = curr->next;
rjp_add_member(root, 0, esc_str, 0, rjp_null()); free(curr);
}else{ break;
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;
} }
} }
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(); char* rfil = restore_file();
FILE* restf = fopen(rfil, "w"); FILE* restf = fopen(rfil, "w");
if(!restf){ if(!restf){
@@ -152,7 +160,7 @@ void save_restore_file(struct string_array* devices){
} }
free(rfil); free(rfil);
rjp_free(tmp); rjp_free(tmp);
rjp_free_value(root); rjp_free_value(rf);
} }

View File

@@ -31,30 +31,38 @@
#include "config.h" #include "config.h"
#ifdef ENABLE_RESTORE_FILE #ifdef ENABLE_RESTORE_FILE
#include <rjp.h>
#include "restore.h" #include "restore.h"
#endif #endif
/////////////////////////////////////////////////////////////////////////////////////////////
#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 //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 //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
const char* device_dir(void){return "/sys/class/leds/";} const char* device_dir(void){return "/sys/class/leds/";}
const char* executable_name(void){return "rexledctl";} const char* executable_name(void){return "rexledctl";}
const char* restore_file_suffix(void){return "/.config/rexledctl.json";} const char* restore_file_suffix(void){return "/.config/rexledctl.json";}
#else #else
#error "UNDEFINED PROGRAM NAME!" #error "UNDEFINED PROGRAM NAME!"
#endif #endif
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;
@@ -80,7 +88,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 '..' //ignore '.' and '..'
if(!strncmp(dir->d_name, ".", 1) || !strncmp(dir->d_name, "..", 2)){ if(!strcmp(dir->d_name, ".") || !strcmp(dir->d_name, "..")){
continue; continue;
} }
@@ -138,6 +146,7 @@ float get_brightness(const char* file){
fclose(bright); fclose(bright);
return atof(buff); return atof(buff);
} }
//return milliseconds since last boot //return milliseconds since last boot
double get_time(void){ double get_time(void){
struct timespec t; struct timespec t;
@@ -154,14 +163,14 @@ 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){
FILE* fd; FILE* fd;
double 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 = arg->act_start; //current value to write to file
double step_delta = (double)arg->fade_duration / arg->fade_steps; double step_delta = (double)arg->fade_duration / arg->fade_steps;
double step_inc = step_delta; 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){ while(arg->fade_duration > tdelta){
//write //write
@@ -196,118 +205,92 @@ void fade_out(struct arg_values* arg, int iv, int fv){
return_value = RETVAL_INVALID_FILE; return_value = RETVAL_INVALID_FILE;
return; return;
} }
fprintf(fd, "%d", fv); fprintf(fd, "%d", arg->act_delta);
fclose(fd); 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 prep_offset(struct arg_values* args){
int do_assignment(struct arg_values* args){ if(chdir(args->device)){
for(;args;args = args->next){ io_error_2(IO_ERROR_OPEN, IO_ERROR_DIR, device_dir(), args->device);
if(chdir(args->device)){ return RETVAL_INVALID_DIR;
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;
}
} }
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 //Run get operation
int do_get(struct arg_values* args){ int do_get(struct arg_values* args){
for(;args;args = args->next){ float curr, max;
float curr, max; if(chdir(args->device)){
if(chdir(args->device)){ io_error_2(IO_ERROR_OPEN, IO_ERROR_DIR, device_dir(), args->device);
io_error_2(IO_ERROR_OPEN, IO_ERROR_DIR, device_dir(), args->device); return RETVAL_INVALID_DIR;
return_value = RETVAL_INVALID_DIR; }
continue; curr = get_brightness(brightness_file());
} max = get_brightness(max_brightness_file());
curr = get_brightness(brightness_file()); if(return_value == RETVAL_INVALID_FILE && (!curr || !max)){
max = get_brightness(max_brightness_file()); fprintf(stdout, "%s", args->device);
if(return_value == RETVAL_INVALID_FILE && (!curr || !max)){ }else{
fprintf(stdout, "%s", args->device); fprintf(stdout, "%-25s %.2f\n", args->device, curr / max * 100);
}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());
if(chdir(device_dir())){ return RETVAL_INVALID_DIR;
io_error(IO_ERROR_OPEN, IO_ERROR_DIR, device_dir());
return RETVAL_INVALID_DIR;
}
} }
return return_value; return return_value;
} }
//Run list operation //Run list operation
void do_list(struct arg_values* args){ void do_list(struct arg_values* args){
for(;args;args = args->next){ printf("%s\n", args->device);
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;
} }
//Run requested operation on a per device basis
int run_device_operations(struct arg_values* a){
int changes = 0;
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 #ifdef ENABLE_RESTORE_FILE
//convert all restore operations to set operations case OP_RESTORE:
void prep_restore(struct arg_values* a){ if(!restore_to_delta(a)){
RJP_value* root = 0; continue;
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);
}
#else
#define prep_restore(x)
#endif #endif
case OP_INC:
//remove all args in src which have the specified operation and append them to dest case OP_DEC:
struct arg_values* extract_operation(int operation, struct arg_values* dest, struct arg_values* src){ case OP_SET:
struct arg_values* curr_dest = dest; if(prep_offset(a))
dest->next = NULL; break;
for(struct arg_values* curr_src = src;curr_src->next;){ ++changes;
if(curr_src->next->operation & operation){ fade_out(a);
extract_next_arg(curr_dest, curr_src); break;
curr_dest = curr_dest->next; };
}else{
curr_src = curr_src->next;
}
} }
return curr_dest; return changes;
}
//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, &current_op_args, a);
do_list(current_op_args.next);
free_cmd_args(&current_op_args);
//get
extract_operation(OP_GET, &current_op_args, a);
return_value = do_get(current_op_args.next);
free_cmd_args(&current_op_args);
//assignment
curr = extract_operation(OP_RESTORE, &current_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(&current_op_args);
} }
//If a global operation is requested, run this to fill arg with all devices, each with the global operation //If a global operation is requested, run this to fill arg with all devices, each with the global operation
@@ -320,6 +303,7 @@ void populate_args(struct arg_values* arg, struct string_array* devices){
curr->next->fade_duration = arg->fade_duration; curr->next->fade_duration = arg->fade_duration;
curr->next->fade_steps = arg->fade_steps; curr->next->fade_steps = arg->fade_steps;
curr->next->operation = arg->operation; curr->next->operation = arg->operation;
curr->next->flags = arg->flags;
curr = curr->next; curr = curr->next;
} }
curr->next = NULL; curr->next = NULL;
@@ -331,6 +315,7 @@ 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.
int should_save = 0;
args = process_cmd_args(argc, argv); args = process_cmd_args(argc, argv);
if(args.operation == OP_USAGE){ if(args.operation == OP_USAGE){
@@ -344,7 +329,7 @@ int main(int argc, char** argv){
//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 backlight devices found!\n");
#elif defined(REXLEDCTL) #elif defined(REXLEDCTL)
fprintf(stderr, "No led devices found!\n"); fprintf(stderr, "No led devices found!\n");
#endif #endif
@@ -375,16 +360,20 @@ int main(int argc, char** argv){
return RETVAL_INVALID_DIR; return RETVAL_INVALID_DIR;
} }
//Run selected operation //on a global operation, populate list with all devices
if(!args.next){ if(!args.next){
populate_args(&args, &device_names); populate_args(&args, &device_names);
} }
run_device_operations(&args); should_save = (run_device_operations(&args) > 0);
#ifdef ENABLE_RESTORE_FILE #ifdef ENABLE_RESTORE_FILE
save_restore_file(&device_names); if(should_save)
save_restore_file(&device_names, &args); //performs cleanup on args
else
free_cmd_args(&args);
#else
free_cmd_args(&args);
#endif #endif
free_string_array(&device_names); free_string_array(&device_names);
free_cmd_args(&args);
return return_value; return return_value;
} }