//Chris Xiong 2018 //3-Clause BSD License #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "utils.hpp" #include "sensor_als.hpp" #include "brightness_ctrl.hpp" SensorALS als; int als_id; bool manualmode; filesystem::path fifo_path; BrightnessControl lcd,kbd; FILE *fifo_f; void als_callback(SensorBase* _s) { SensorALS* s=(SensorALS*)_s; float val=s->get_value(); lcd.on_sensor_report(val); kbd.on_sensor_report(val); } std::vector numlist2vec(std::string l) { std::vector v; split(l,',',v); std::vector r; for(auto&i:v)r.push_back(atoi(i.c_str())); return r; } void load_config() { fifo_path="/tmp/lightsd.cmd.fifo"; FILE* cfgf; cfgf=fopen("/etc/lightsd.conf","r"); if(!cfgf) cfgf=fopen("lightsd.conf","r"); if(!cfgf)return (void)LOG('W',"Configuration file not found.",0); char* buf=new char[1024]; while(!feof(cfgf)) { ignore_result(fgets(buf,1024,cfgf)); if(buf[0]=='#')continue; std::string sb=trim(buf); std::vector sv; split(sb,'=',sv); if(sv.size()!=2)continue; if(sv[0]=="lcd_backlight_control")lcd.set_path(sv[1]); if(sv[0]=="kbd_backlight_control")kbd.set_path(sv[1]); if(sv[0]=="lcd_backlight_thresholds")lcd.set_thresh(numlist2vec(sv[1])); if(sv[0]=="lcd_backlight_values")lcd.set_value(numlist2vec(sv[1])); if(sv[0]=="lcd_backlight_control_delay")lcd.set_delay(atoi(sv[1].c_str())); if(sv[0]=="lcd_backlight_trigger_range")lcd.set_trigrange(atoi(sv[1].c_str())); if(sv[0]=="lcd_backlight_min_value")lcd.set_minabr(atoi(sv[1].c_str())); if(sv[0]=="kbd_backlight_thresholds")kbd.set_thresh(numlist2vec(sv[1])); if(sv[0]=="kbd_backlight_values")kbd.set_value(numlist2vec(sv[1])); if(sv[0]=="kbd_backlight_control_delay")kbd.set_delay(atoi(sv[1].c_str())); if(sv[0]=="kbd_backlight_trigger_range")kbd.set_trigrange(atoi(sv[1].c_str())); if(sv[0]=="kbd_backlight_min_value")kbd.set_minabr(atoi(sv[1].c_str())); if(sv[0]=="command_fifo_path")fifo_path=sv[1]; if(sv[0]=="als_print_value")als.set_debug(sv[1]=="true"); } delete[] buf; } int get_gid(std::string group) { FILE* grpf=fopen("/etc/group","r"); char* buf=new char[1024]; while(!feof(grpf)) { ignore_result(fgets(buf,1024,grpf)); std::vector sv; split(buf,':',sv); if(sv[0]==group) { fclose(grpf); delete[] buf; return atoi(sv[2].c_str()); } } fclose(grpf); delete[] buf; return -1; } void cleanup() { als.quit_worker(); if(!fifo_path.empty())unlink(fifo_path.c_str()); } void sighandler(int) { if(!fifo_path.empty())//command thread *exists* { FILE* tf=fopen(fifo_path.c_str(),"w"); fputs("q\n",tf); //let the command thread cleanup fclose(tf); } else cleanup(); } void setup_fifo() { if(fifo_path.empty())return; int ret=0; unlink(fifo_path.c_str()); ret|=mkfifo(fifo_path.c_str(),0220); ret|=chown(fifo_path.c_str(),0,get_gid("video")); ret|=chmod(fifo_path.c_str(),0220); if(ret) { LOG('W',"Failed to create fifo.",0); unlink(fifo_path.c_str()); fifo_path=""; } } void command_thread() { if(fifo_path.empty())return; fifo_f=fopen(fifo_path.c_str(),"r"); char cmdbuf[256]; while(1) { ignore_result(fgets(cmdbuf,256,fifo_f)); LOG('I',"got command: %s",trim(cmdbuf).c_str()); std::vector cav; split(trim(cmdbuf),' ',cav); if(cav.size()>=1) { if(cav[0]=="u") { if(cav.size()>1)lcd.set_offset(1,atoi(cav[1].c_str())); else lcd.set_offset(1,5); } if(cav[0]=="d") { if(cav.size()>1)lcd.set_offset(-1,atoi(cav[1].c_str())); else lcd.set_offset(-1,5); } if(cav[0]=="s")if(cav.size()>1)lcd.set_offset(0,atoi(cav[1].c_str())); if(cav[0]=="r"&&!manualmode)lcd.set_offset(0,0); if(cav[0]=="f"&&!manualmode) { lcd.force_adjust(); kbd.force_adjust(); } if(cav[0]=="m") if(!manualmode) { als.pause_worker(); lcd.set_frozen(true); kbd.set_frozen(true); manualmode=true; } if(cav[0]=="a") if(manualmode) { manualmode=false; als.resume_worker(); lcd.set_frozen(false); kbd.set_frozen(false); } if(cav[0]=="i") { printf("Mode: %s\n",manualmode?"Manual":"Automatic"); printf(manualmode?"ALS value: --\n":"ALS value: %.2f\n",als.get_value()); printf("Display brightness: %d%%",lcd.get_brightness()); if(!manualmode&&lcd.get_offset())printf(" (+%d%%)\n",lcd.get_offset());else putchar('\n'); //TODO: do not print this if keyboard backlight is not managed printf("Keyboard backlight: %d%%\n",kbd.get_brightness()); } if(cav[0]=="q") { fclose(fifo_f); cleanup(); return; } } fclose(fifo_f); fifo_f=fopen(fifo_path.c_str(),"r"); } } int main() { signal(SIGTERM,sighandler); signal(SIGINT,sighandler); als_id=SensorBase::detect_sensor("als"); if(!~als_id)return puts("No ALS found!"),1; if(als.init(als_id,"in_intensity"))return puts("Failed to initialize sensor."),1; als.set_reader_callback(als_callback); float init_val=als.get_value(); manualmode=false; load_config(); setup_fifo(); lcd.init(init_val,&als); kbd.init(init_val,&als); std::thread (&BrightnessControl::worker,std::ref(lcd)).detach(); std::thread (&BrightnessControl::worker,std::ref(kbd)).detach(); std::thread (command_thread).detach(); als.worker(); _exit(0); }