Split into multiple source files
This commit is contained in:
parent
8137a8ffa9
commit
a3c32e5e7f
69
include/cmd.h
Normal file
69
include/cmd.h
Normal file
@ -0,0 +1,69 @@
|
||||
/**
|
||||
rexbacklight
|
||||
Copyright (C) 2018 rexy712
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef RECBACKLIGHT_CMD_H
|
||||
#define REXBACKLIGHT_CMD_H
|
||||
|
||||
#define OP_SET 4
|
||||
#define OP_LIST 8
|
||||
#define OP_GET 128
|
||||
#define OP_NONE 0
|
||||
|
||||
#define GET_LONG_OPT "--get"
|
||||
#define GET_SHORT_OPT "-g"
|
||||
#define FADE_LONG_OPT "--fade"
|
||||
#define FADE_SHORT_OPT "-f"
|
||||
#define DEVICE_LONG_OPT "--device"
|
||||
#define DEVICE_SHORT_OPT "-d"
|
||||
#define LIST_LONG_OPT "--list"
|
||||
#define LIST_SHORT_OPT "-l"
|
||||
#define HELP_LONG_OPT "--help"
|
||||
#define HELP_SHORT_OPT "-h"
|
||||
|
||||
struct cmd_arg{
|
||||
const char* lopt;
|
||||
const char* sopt;
|
||||
const char* desc;
|
||||
};
|
||||
|
||||
extern struct cmd_arg rexbacklight_args[];
|
||||
extern int rexbacklight_args_length;
|
||||
|
||||
struct arg_values{
|
||||
struct arg_values* next;
|
||||
|
||||
//Specific device to control
|
||||
//NULL means all devices
|
||||
const char* device;
|
||||
|
||||
//What value to put in the backlight file
|
||||
char* delta;
|
||||
|
||||
//How many seconds to transition
|
||||
int fade_duration;
|
||||
|
||||
unsigned char operation;
|
||||
};
|
||||
|
||||
|
||||
|
||||
void free_cmd_args(struct arg_values* a);
|
||||
struct arg_values process_cmd_args(int argc, char** argv);
|
||||
int process_op(char* arg, float min, float current, float max);
|
||||
|
||||
#endif
|
||||
34
include/common.h
Normal file
34
include/common.h
Normal file
@ -0,0 +1,34 @@
|
||||
/**
|
||||
rexbacklight
|
||||
Copyright (C) 2018 rexy712
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifndef REXBACKLIGHT_COMMON_H
|
||||
#define REXBACKLIGHT_COMMON_H
|
||||
|
||||
#define RETVAL_INVALID_FILE 1
|
||||
#define RETVAL_INVALID_DIR 2
|
||||
#define RETVAL_UNRECOGNIZED_OPTION 3
|
||||
#define RETVAL_MISSING_OPTION 4
|
||||
#define RETVAL_INVALID_DEVICE -5
|
||||
#define RETVAL_SUCCESS EXIT_SUCCESS
|
||||
|
||||
_Noreturn void usage(int exit_val);
|
||||
|
||||
|
||||
#endif
|
||||
83
makefile
83
makefile
@ -1,25 +1,72 @@
|
||||
.PHONY: all
|
||||
all: rexbacklight
|
||||
#Copyright 2018 rexy712 of Rexy & Co
|
||||
#Makefile for project 'rexbacklight'
|
||||
|
||||
rexbacklight: src/rexbacklight.c
|
||||
gcc -std=c11 -g -Wall -Wextra -pedantic src/rexbacklight.c -o rexbacklight
|
||||
#Project directory and file setup
|
||||
SOURCE_DIRS:=src
|
||||
OBJDIR:=obj
|
||||
DEPDIR:=obj/dep
|
||||
INCLUDE_DIRS:=include
|
||||
EXT:=c
|
||||
MAIN_EXECUTABLE:=rexbacklight
|
||||
|
||||
#Compiler/Linker setup
|
||||
CC:=gcc
|
||||
CFLAGS:=-g -std=c11 -Wall -pedantic -Wextra
|
||||
release: CFLAGS:=-std=c11 -Wall -pedantic -Wextra -O2
|
||||
LDFLAGS=
|
||||
LDLIBS:=
|
||||
STRIP:=strip
|
||||
|
||||
#Windows workarounds
|
||||
ifeq ($(OS),Windows_NT)
|
||||
mkdir=mkdir $(subst /,\,$(1)) > NUL 2>&1
|
||||
rm=del /F $(1) > NUL 2>&1
|
||||
rmdir=rd /s /q $(1) > NUL 2>&1
|
||||
move=move /y $(subst /,\,$(1)) $(subst /,\,$(2)) > NUL 2>&1
|
||||
MAIN_EXECUTABLE:=$(MAIN_EXECUTABLE).exe
|
||||
LDLIBS:=
|
||||
else
|
||||
mkdir=mkdir -p $(1)
|
||||
rm=rm -f $(1)
|
||||
rmdir=rm -rf $(1)
|
||||
move=mv $(1) $(2)
|
||||
endif
|
||||
|
||||
#Internal management of sources/objects and additional cflags
|
||||
INTERNAL_CFLAGS=-c $(foreach dir,$(INCLUDE_DIRS),-I"$(dir)") -MMD -MP -MF"$(DEPDIR)/$*.d"
|
||||
SOURCES:=$(foreach source,$(SOURCE_DIRS),$(foreach ext,$(EXT),$(wildcard $(source)/*.$(ext))))
|
||||
OBJECTS:=$(addprefix $(OBJDIR)/,$(subst \,.,$(subst /,.,$(addsuffix .o,$(SOURCES)))))
|
||||
|
||||
all: $(MAIN_EXECUTABLE)
|
||||
|
||||
$(MAIN_EXECUTABLE): $(OBJECTS)
|
||||
$(CC) $(LDFLAGS) $^ -o "$(basename $@)" $(LDLIBS)
|
||||
|
||||
.PHONY: release
|
||||
release: src/rexbacklight.c
|
||||
gcc -std=c11 -O2 -Wall -Wextra -pedantic src/rexbacklight.c -o rexbacklight
|
||||
strip --strip-all rexbacklight
|
||||
release: $(OBJECTS)
|
||||
$(CC) $(LDFLAGS) $^ -o "$(basename $(MAIN_EXECUTABLE))" $(LDLIBS)
|
||||
$(STRIP) --strip-all "$(MAIN_EXECUTABLE)"
|
||||
|
||||
.PHONY: install
|
||||
install: rexbacklight
|
||||
install -m755 -o root -g root -s rexbacklight /usr/bin/rexbacklight
|
||||
install -m600 -o root -g root rules/91-backlight.rules /etc/udev/rules.d/91-backlight.rules
|
||||
install -m755 -o root -g root rules/backlight /etc/init.d/backlight
|
||||
define GENERATE_OBJECTS
|
||||
|
||||
$$(OBJDIR)/$(subst \,.,$(subst /,.,$(1))).%.o: $(1)/%
|
||||
$$(CC) $$(CFLAGS) $$(INTERNAL_CFLAGS) "$$<" -o "$$@"
|
||||
|
||||
endef
|
||||
|
||||
$(foreach dir,$(SOURCE_DIRS),$(eval $(call GENERATE_OBJECTS,$(dir))))
|
||||
$(OBJECTS): | $(OBJDIR) $(DEPDIR)
|
||||
|
||||
$(OBJDIR):
|
||||
$(call mkdir,"$@")
|
||||
$(DEPDIR):
|
||||
$(call mkdir,"$@")
|
||||
|
||||
.PHONY: uninstall
|
||||
uninstall:
|
||||
rm /usr/bin/rexbacklight
|
||||
rm /etc/udev/rules.d/91-backlight.rules
|
||||
rm /etc/init.d/backlight
|
||||
.PHONY: clean
|
||||
clean:
|
||||
rm rexbacklight
|
||||
$(call rmdir,"$(DEPDIR)")
|
||||
$(call rmdir,"$(OBJDIR)")
|
||||
$(call rm,"$(MAIN_EXECUTABLE)")
|
||||
-include $(wildcard $(DEPDIR)/*.d)
|
||||
|
||||
|
||||
|
||||
196
src/cmd.c
Normal file
196
src/cmd.c
Normal file
@ -0,0 +1,196 @@
|
||||
/**
|
||||
rexbacklight
|
||||
Copyright (C) 2018 rexy712
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "cmd.h"
|
||||
#include "common.h"
|
||||
|
||||
#define CHECK_OPTION(opt, arg) (!strcmp(opt##_LONG_OPT, arg) || !strcmp(opt##_SHORT_OPT, arg))
|
||||
|
||||
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"},
|
||||
{GET_LONG_OPT, GET_SHORT_OPT, "TODO: print current brightness level to stdout"},
|
||||
{LIST_LONG_OPT, LIST_SHORT_OPT, "TODO: print device names to stdout and exit"},
|
||||
{HELP_LONG_OPT, HELP_SHORT_OPT, "print this help message and exit"}
|
||||
};
|
||||
int rexbacklight_args_length = sizeof(rexbacklight_args) / sizeof(rexbacklight_args[0]);
|
||||
|
||||
void free_cmd_args(struct arg_values* a){
|
||||
if(!a->next)
|
||||
return;
|
||||
free_cmd_args(a->next);
|
||||
free(a->next);
|
||||
}
|
||||
|
||||
#define CHECK_NEXT_ARG(rval) \
|
||||
do{ \
|
||||
if(i == argc - 1){ \
|
||||
fprintf(stderr, "Missing argument to '%s'\n\n", argv[i]); \
|
||||
free_cmd_args(&ret); \
|
||||
usage(rval); \
|
||||
} \
|
||||
}while(0)
|
||||
#define UNRECOGNIZED_OPTION(rval) \
|
||||
do{ \
|
||||
fprintf(stderr, "Unrecognized command line option '%s'\n\n", argv[i]); \
|
||||
free_cmd_args(&ret); \
|
||||
usage(rval); \
|
||||
}while(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* curr = &ret;
|
||||
|
||||
//Skip argv[0]
|
||||
for(int i = 1;i < argc;i++){
|
||||
|
||||
//Check for switches
|
||||
if(CHECK_OPTION(GET, argv[i])){
|
||||
curr->operation |= OP_GET;
|
||||
continue;
|
||||
|
||||
}else if(CHECK_OPTION(FADE, argv[i])){
|
||||
CHECK_NEXT_ARG(-5);
|
||||
curr->fade_duration = 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));
|
||||
curr = curr->next;
|
||||
curr->device = argv[++i];
|
||||
continue;
|
||||
}
|
||||
else if(CHECK_OPTION(LIST, argv[i])){
|
||||
free_cmd_args(&ret);
|
||||
ret.operation = OP_LIST;
|
||||
ret.next = NULL;
|
||||
return ret;
|
||||
}
|
||||
else if(CHECK_OPTION(HELP, argv[i])){
|
||||
free_cmd_args(&ret);
|
||||
usage(RETVAL_SUCCESS);
|
||||
}
|
||||
|
||||
else if(!strcmp(argv[i], "max")){
|
||||
curr->operation = OP_SET;
|
||||
curr->delta = argv[i];
|
||||
}
|
||||
else if(!strcmp(argv[i], "min")){
|
||||
curr->operation = OP_SET;
|
||||
curr->delta = argv[i];
|
||||
}
|
||||
else if(!strcmp(argv[i], "off")){
|
||||
curr->operation = OP_SET;
|
||||
curr->delta = argv[i];
|
||||
}
|
||||
|
||||
//If we get a '-' followed by not a number, it's not a known option
|
||||
else if(argv[i][1] < '0' || argv[i][1] > '9'){
|
||||
UNRECOGNIZED_OPTION(RETVAL_UNRECOGNIZED_OPTION);
|
||||
}
|
||||
|
||||
//If we get a '-' followed by a number, it's a decrement request
|
||||
else{
|
||||
curr->operation = OP_SET;
|
||||
curr->delta = argv[i];
|
||||
}
|
||||
}
|
||||
|
||||
//If there isn't an operation defined in the global context and there is no specified device, there's nothing to do
|
||||
if(!ret.operation){
|
||||
if(!ret.next){
|
||||
fprintf(stderr, "No operation requested!\n\n");
|
||||
usage(RETVAL_MISSING_OPTION);
|
||||
}
|
||||
//if there is a device specified, make sure each one has a requested operation
|
||||
for(curr = ret.next;curr;curr = curr->next){
|
||||
if(!curr->operation){
|
||||
fprintf(stderr, "No operation requested for device '%s'!\n\n", curr->device);
|
||||
free_cmd_args(&ret);
|
||||
usage(RETVAL_MISSING_OPTION);
|
||||
}
|
||||
}
|
||||
//If there is a globally defined operation, apply it to the devices with no operation request
|
||||
}else{
|
||||
for(curr = ret.next;curr;curr = curr->next){
|
||||
if(curr->operation == OP_NONE){
|
||||
curr->operation = ret.operation;
|
||||
if(!curr->delta)
|
||||
curr->delta = ret.delta;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
#undef CHECK_OPTION
|
||||
#undef UNRECOGNIZED_OPTION
|
||||
|
||||
//Process an operation
|
||||
int process_op(char* arg, float min, float current, float max){
|
||||
//Amount to inc/dec
|
||||
int delta = delta = max * atof(arg + 1) / 100.0;
|
||||
|
||||
//Increment
|
||||
if(arg[0] == '+'){
|
||||
delta = delta + current;
|
||||
if(delta >= max)
|
||||
return max;
|
||||
else{
|
||||
return delta;
|
||||
}
|
||||
|
||||
//Decrement
|
||||
}else if(arg[0] == '-'){
|
||||
delta = current - delta;
|
||||
if(delta <= min)
|
||||
return min;
|
||||
else
|
||||
return delta;
|
||||
|
||||
//Directly set
|
||||
}else if(arg[0] == '='){
|
||||
if(delta >= max)
|
||||
return max;
|
||||
else if(delta <= min)
|
||||
return min;
|
||||
else
|
||||
return delta;
|
||||
|
||||
//Set to minimum plus one (so backlight is actually on!)
|
||||
}else if(!strcmp("min", arg)){
|
||||
return min + 1;
|
||||
|
||||
//Turn off backlight
|
||||
}else if(!strcmp("off", arg)){
|
||||
return min;
|
||||
|
||||
//Set to maximum
|
||||
}else if(!strcmp("max", arg)){
|
||||
return max;
|
||||
}
|
||||
return current;
|
||||
}
|
||||
|
||||
50
src/common.c
Normal file
50
src/common.c
Normal file
@ -0,0 +1,50 @@
|
||||
/**
|
||||
rexbacklight
|
||||
Copyright (C) 2018 rexy712
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
#include "cmd.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
_Noreturn void usage(int exit_val){
|
||||
fprintf(stderr, "Usage: rexbacklight [argument] [options] [argument]\n\n");
|
||||
|
||||
fprintf(stderr, "Options:\n");
|
||||
for(int i = 0;i < rexbacklight_args_length;i++){
|
||||
fprintf(stderr, " %s|%s\n", rexbacklight_args[i].lopt, rexbacklight_args[i].sopt);
|
||||
fprintf(stderr, " %s\n", rexbacklight_args[i].desc);
|
||||
}
|
||||
fprintf(stderr, "\n");
|
||||
fprintf(stderr, "Arguments:\n");
|
||||
fprintf(stderr, " =<percentage>\n");
|
||||
fprintf(stderr, " -<percentage>\n");
|
||||
fprintf(stderr, " +<percentage>\n");
|
||||
fprintf(stderr, " off\n");
|
||||
fprintf(stderr, " max\n");
|
||||
fprintf(stderr, " min\n");
|
||||
|
||||
if(exit_val == RETVAL_SUCCESS){
|
||||
fprintf(stderr, "\nrexbacklight Copyright (C) 2018 rexy712\n");
|
||||
fprintf(stderr, "This program comes with ABSOLUTELY NO WARRANTY.\n");
|
||||
fprintf(stderr, "This is free software, and you are welcome to redistribute it\n");
|
||||
fprintf(stderr, "under certain conditions; see the GNU GPLv3 for details.\n");
|
||||
fprintf(stderr, "A copy of the GPLv3 is available with the source in the file 'LICENSE'\n");
|
||||
}
|
||||
|
||||
exit(exit_val);
|
||||
}
|
||||
@ -19,247 +19,20 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <dirent.h>
|
||||
#include <errno.h>
|
||||
|
||||
#define OP_SET 4
|
||||
#define OP_GET 128
|
||||
#define OP_NONE 0
|
||||
|
||||
#define GET_LONG_OPT "--get"
|
||||
#define GET_SHORT_OPT "-g"
|
||||
#define FADE_LONG_OPT "--fade"
|
||||
#define FADE_SHORT_OPT "-f"
|
||||
#define DEVICE_LONG_OPT "--device"
|
||||
#define DEVICE_SHORT_OPT "-d"
|
||||
#define HELP_LONG_OPT "--help"
|
||||
#define HELP_SHORT_OPT "-h"
|
||||
|
||||
#define CHECK_OPTION(opt, arg) (!strcmp(opt##_LONG_OPT, arg) || !strcmp(opt##_SHORT_OPT, arg))
|
||||
|
||||
#define RETVAL_INVALID_FILE -1
|
||||
#define RETVAL_INVALID_DIR -2
|
||||
#define RETVAL_UNRECOGNIZED_OPTION -3
|
||||
#define RETVAL_MISSING_OPTION -4
|
||||
#define RETVAL_INVALID_DEVICE -5
|
||||
#define RETVAL_SUCCESS EXIT_SUCCESS
|
||||
|
||||
struct string_array{
|
||||
char** list;
|
||||
int size;
|
||||
};
|
||||
|
||||
struct arg_values{
|
||||
struct arg_values* next;
|
||||
|
||||
//Specific device to control
|
||||
//NULL means all devices
|
||||
const char* device;
|
||||
|
||||
//What value to put in the backlight file
|
||||
char* delta;
|
||||
|
||||
//How many seconds to transition
|
||||
int fade_duration;
|
||||
|
||||
unsigned char operation;
|
||||
};
|
||||
|
||||
|
||||
#include "common.h"
|
||||
#include "cmd.h"
|
||||
|
||||
//This is where backlight devices can be found in sysfs
|
||||
static const char* backlight_dir = "/sys/class/backlight/";
|
||||
static const char* backlight_file = "brightness";
|
||||
static const char* max_backlight_file = "max_brightness";
|
||||
|
||||
//Print out usage message and GPL message if not caused by an error
|
||||
_Noreturn void usage(int exit_val){
|
||||
fprintf(stderr, "Usage: rexbacklight [argument] [options] [argument]\n\n");
|
||||
|
||||
fprintf(stderr, "Options:\n");
|
||||
fprintf(stderr, " %s|%s\n", DEVICE_SHORT_OPT, DEVICE_LONG_OPT);
|
||||
fprintf(stderr, " select which device to control\n");
|
||||
fprintf(stderr, " %s|%s\n", FADE_SHORT_OPT, FADE_LONG_OPT);
|
||||
fprintf(stderr, " TODO: change brightness over time interval\n");
|
||||
fprintf(stderr, " %s|%s\n", GET_SHORT_OPT, GET_LONG_OPT);
|
||||
fprintf(stderr, " TODO: print the current brightness level to stdout\n");
|
||||
fprintf(stderr, " %s|%s\n", HELP_SHORT_OPT, HELP_LONG_OPT);
|
||||
fprintf(stderr, " print this help message and exit\n");
|
||||
fprintf(stderr, "\n");
|
||||
fprintf(stderr, "Arguments:\n");
|
||||
fprintf(stderr, " =<percentage>\n");
|
||||
fprintf(stderr, " -<percentage>\n");
|
||||
fprintf(stderr, " +<percentage>\n");
|
||||
fprintf(stderr, " off\n");
|
||||
fprintf(stderr, " max\n");
|
||||
fprintf(stderr, " min\n");
|
||||
|
||||
if(exit_val == RETVAL_SUCCESS){
|
||||
fprintf(stderr, "\nrexbacklight Copyright (C) 2018 rexy712\n");
|
||||
fprintf(stderr, "This program comes with ABSOLUTELY NO WARRANTY.\n");
|
||||
fprintf(stderr, "This is free software, and you are welcome to redistribute it\n");
|
||||
fprintf(stderr, "under certain conditions; see the GNU GPLv3 for details.\n");
|
||||
fprintf(stderr, "A copy of the GPLv3 is available with the source in the file 'LICENSE'\n");
|
||||
}
|
||||
|
||||
exit(exit_val);
|
||||
}
|
||||
|
||||
void free_cmd_args(struct arg_values* a){
|
||||
if(!a->next)
|
||||
return;
|
||||
free_cmd_args(a->next);
|
||||
free(a->next);
|
||||
}
|
||||
|
||||
#define CHECK_NEXT_ARG(rval) \
|
||||
do{ \
|
||||
if(i == argc - 1){ \
|
||||
fprintf(stderr, "Missing argument to '%s'\n\n", argv[i]); \
|
||||
free_cmd_args(&ret); \
|
||||
usage(rval); \
|
||||
} \
|
||||
}while(0)
|
||||
#define UNRECOGNIZED_OPTION(rval) \
|
||||
do{ \
|
||||
fprintf(stderr, "Unrecognized command line option '%s'\n\n", argv[i]); \
|
||||
free_cmd_args(&ret); \
|
||||
usage(rval); \
|
||||
}while(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* curr = &ret;
|
||||
|
||||
//Skip argv[0]
|
||||
for(int i = 1;i < argc;i++){
|
||||
|
||||
//Check for switches
|
||||
if(CHECK_OPTION(GET, argv[i])){
|
||||
curr->operation |= OP_GET;
|
||||
continue;
|
||||
|
||||
}else if(CHECK_OPTION(FADE, argv[i])){
|
||||
CHECK_NEXT_ARG(-5);
|
||||
curr->fade_duration = 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));
|
||||
curr = curr->next;
|
||||
curr->device = argv[++i];
|
||||
continue;
|
||||
}
|
||||
else if(CHECK_OPTION(HELP, argv[i])){
|
||||
free_cmd_args(&ret);
|
||||
usage(RETVAL_SUCCESS);
|
||||
}
|
||||
|
||||
else if(!strcmp(argv[i], "max")){
|
||||
curr->operation = OP_SET;
|
||||
curr->delta = argv[i];
|
||||
}
|
||||
else if(!strcmp(argv[i], "min")){
|
||||
curr->operation = OP_SET;
|
||||
curr->delta = argv[i];
|
||||
}
|
||||
else if(!strcmp(argv[i], "off")){
|
||||
curr->operation = OP_SET;
|
||||
curr->delta = argv[i];
|
||||
}
|
||||
|
||||
//If we get a '-' followed by not a number, it's not a known option
|
||||
else if(argv[i][1] < '0' || argv[i][1] > '9'){
|
||||
UNRECOGNIZED_OPTION(RETVAL_UNRECOGNIZED_OPTION);
|
||||
}
|
||||
|
||||
//If we get a '-' followed by a number, it's a decrement request
|
||||
else{
|
||||
curr->operation = OP_SET;
|
||||
curr->delta = argv[i];
|
||||
}
|
||||
}
|
||||
|
||||
//If there isn't an operation defined in the global context and there is no specified device, there's nothing to do
|
||||
if(!ret.operation){
|
||||
if(!ret.next){
|
||||
fprintf(stderr, "No operation requested!\n\n");
|
||||
usage(RETVAL_MISSING_OPTION);
|
||||
}
|
||||
//if there is a device specified, make sure each one has a requested operation
|
||||
for(curr = ret.next;curr;curr = curr->next){
|
||||
if(!curr->operation){
|
||||
fprintf(stderr, "No operation requested for device '%s'!\n\n", curr->device);
|
||||
free_cmd_args(&ret);
|
||||
usage(RETVAL_MISSING_OPTION);
|
||||
}
|
||||
}
|
||||
//If there is a globally defined operation, apply it to the devices with no operation request
|
||||
}else{
|
||||
for(curr = ret.next;curr;curr = curr->next){
|
||||
if(curr->operation == OP_NONE){
|
||||
curr->operation = ret.operation;
|
||||
if(!curr->delta)
|
||||
curr->delta = ret.delta;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
#undef CHECK_OPTION
|
||||
#undef UNRECOGNIZED_OPTION
|
||||
|
||||
//Process an operation
|
||||
int process_op(char* arg, float min, float current, float max){
|
||||
//Amount to inc/dec
|
||||
int delta = delta = max * atof(arg + 1) / 100.0;
|
||||
|
||||
//Increment
|
||||
if(arg[0] == '+'){
|
||||
delta = delta + current;
|
||||
if(delta >= max)
|
||||
return max;
|
||||
else{
|
||||
return delta;
|
||||
}
|
||||
|
||||
//Decrement
|
||||
}else if(arg[0] == '-'){
|
||||
delta = current - delta;
|
||||
if(delta <= min)
|
||||
return min;
|
||||
else
|
||||
return delta;
|
||||
|
||||
//Directly set
|
||||
}else if(arg[0] == '='){
|
||||
if(delta >= max)
|
||||
return max;
|
||||
else if(delta <= min)
|
||||
return min;
|
||||
else
|
||||
return delta;
|
||||
|
||||
//Set to minimum plus one (so backlight is actually on!)
|
||||
}else if(!strcmp("min", arg)){
|
||||
return min + 1;
|
||||
|
||||
//Turn off backlight
|
||||
}else if(!strcmp("off", arg)){
|
||||
return min;
|
||||
|
||||
//Set to maximum
|
||||
}else if(!strcmp("max", arg)){
|
||||
return max;
|
||||
}
|
||||
return current;
|
||||
}
|
||||
struct string_array{
|
||||
char** list;
|
||||
int size;
|
||||
};
|
||||
|
||||
//Delete the list of backlight devices
|
||||
void free_string_array(struct string_array* s){
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user