#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <getopt.h>
#include <stdbool.h>
#include <libgen.h>
#include <signal.h>
#define INADEQUATE_CONDITIONS 3
#define CMD_SIZE 80
#define BUF_SIZE 20
#define BACKLIGHT_DEV "/sys/class/backlight/backlight"
//该程序提供了另一种自带驱动的方式
enum Type { ACTUAL, MAX };
/* Exit flag */
volatile bool g_quit = false;
/* Short option names */
static const char g_shortopts [] = ":vh";
/* Option names */
static const struct option g_longopts [] = {
{ "version", no_argument, NULL, 'v' },
{ "help", no_argument, NULL, 'h' },
{ 0, 0, 0, 0 }
};
static void usage(FILE *fp, int argc, char **argv) {
fprintf(fp,
"Usage: %s [options]\n\n"
"Options:\n"
" -v | --version Display version information\n"
" -h | --help Show help content\n\n"
"", basename(argv[0]));
}
static void opt_parsing_err_handle(int argc, char **argv, int flag) {
/* Exit if no input parameters are entered */
int state = 0;
/* Feedback Error parameter information then exit */
if (optind < argc || flag) {
printf("Error: Parameter parsing failed\n");
if (flag)
printf("\tunrecognized option '%s'\n", argv[optind-1]);
while (optind < argc) {
printf("\tunrecognized option '%s'\n", argv[optind++]);
}
state = -1;
}
if (state == -1) {
printf("Tips: '-h' or '--help' to get help\n\n");
exit(2);
}
}
void sig_handle(int arg) {
g_quit = true;
}
static int get_backlight(int type) {
FILE *fp;
char cmd[CMD_SIZE];
char buf[BUF_SIZE];
switch (type) {
case ACTUAL:
snprintf(cmd, CMD_SIZE, "cat %s/actual_brightness", BACKLIGHT_DEV);
break;
case MAX:
snprintf(cmd, CMD_SIZE, "cat %s/max_brightness", BACKLIGHT_DEV);
break;
default:
return -1;
break;
}
fp = popen(cmd, "r"); //注意该函数同fork效果类似 ,Windows不支持 ,以子进程的方式打开,通常该函数调用的都是控制台命令字符串!
//这里判断一下fp==NULL 抛出异常
fgets(buf, sizeof(buf), fp); //从文件读一行字符到buf ,#include <stdio.h>
//这里判断一下fgets返回值==NULL 抛出异常
pclose (fp);
return atoi(buf);
}
/***************************************************
函数原型:int snprintf(char* dest_str,size_t size,const char* format,...);
所需头文件:#include<stdio.h>
函数功能:先将可变参数 “…” 按照format的格式格式化为字符串,然后再将其拷贝至dest_str中。
注意事项:如果格式化后的字符串长度小于size,则将字符串全部拷贝至dest_str中,并在字符串结尾处加上‘\0’;
如果格式化后的字符串长度大于或等于size,则将字符串的(size-1)拷贝至dest_str中,然后在字符串结尾处加上’\0’.
函数返回值是 格式化字符串的长度。
***************************************************/
int set_brightness(int value) {
char cmd[CMD_SIZE];
snprintf(cmd, CMD_SIZE, "echo %d > %s/brightness", value, BACKLIGHT_DEV);
if ((system(cmd)) != 0) //执行系统命令,等同控制台直接输入
return -1;
return 0;
}
int main(int argc, char **argv) {
int c = 0;
int flag = 0;
int actual_value = -1;
int max_value = -1;
/* Parsing input parameters */
while ((c = getopt_long(argc, argv, g_shortopts, g_longopts, NULL)) != -1) {
switch (c) {
case 'v':
/* Display the version */
printf("version : 1.0\n");
exit(0);
case 'h':
usage(stdout, argc, argv);
exit(0);
default :
flag = 1;
break;
}
}
opt_parsing_err_handle(argc, argv, flag);
/* Ctrl+c handler */
signal(SIGINT, sig_handle);
actual_value = get_backlight(ACTUAL);
if (actual_value < 0) {
printf("Error: Get actual brightness value error\n");
return INADEQUATE_CONDITIONS;
}
printf("Actual backlight is:%d\n", actual_value);
max_value = get_backlight(MAX);
if (max_value < 0) {
printf("Error: Get max brightness value error\n");
return INADEQUATE_CONDITIONS;
}
printf("Max backlight is:%d\n", max_value);
/* loop to brighten backlight */
while (!g_quit) {
/* brighten backlight */
set_brightness(max_value);
usleep(1000000);
set_brightness(max_value * 0.8);
usleep(250000);
set_brightness(max_value * 0.6);
usleep(250000);
set_brightness(max_value * 0.4);
usleep(250000);
set_brightness(max_value * 0.2);
usleep(250000);
set_brightness(0);
usleep(250000);
}
/* get back to actual backlight */
set_brightness(actual_value);
return 0;
}