#include "power_console.h" #include #include #include #include #include #include #include #include #include #include "ConfigFile.h" #include "power_profile.h" #include "backlight.h" namespace C { const bool debug= false; const bool debugUpdate= false or C::debugUpdate; // NOTE: This one can be REALLY floody, if the updates are happening on schedule const bool debugUpdateCalled= false or C::debug; const double updateTimeout= 0.1; const std::filesystem::path defaultConservePath= "/sys/devices/pci0000:00/0000:00:1f.0/PNP0C09:00/VPC2004:00/conservation_mode"; const std::filesystem::path defaultPowerPath= "/sys/class/power_supply/ADP0"; const std::filesystem::path defaultBatteryPath= "/sys/class/power_supply/BAT0"; const std::filesystem::path defaultBacklightPath= "/sys/class/backlight/intel_backlight"; const std::filesystem::path path= "/"; } const std::map< int, Fl_Color > levelColors= { { 15, FL_DARK_RED }, { 33, FL_RED }, { 45, FL_DARK_YELLOW }, { 66, FL_YELLOW }, { 75, FL_DARK_GREEN }, { 90, FL_GREEN }, { 100, FL_BLUE }, }; using Config::exports::ConfigFile; std::unique_ptr< ConfigFile > config; std::filesystem::path getBacklightPath() { return config->get( "backlight_path" ); } std::string battLevelString= "UNKNOWN"; void scheduledUpdate( void * ) { // Ensure we get called again, on schedule: Fl::repeat_timeout( C::updateTimeout, scheduledUpdate, nullptr ); if( C::debugUpdateCalled ) std::cerr << "Update!" << std::endl; std::ifstream batt{ C::path / config->get( "battery_path" ) / "capacity" }; batt >> battLevelString; std::istringstream iss{ battLevelString }; int battlevel= 2; iss >> battlevel; level->value( battlevel ); level->selection_color( levelColors.upper_bound( battlevel )->second ); if( C::debugUpdate ) std::cerr << "Battery state read as: " << battlevel << std::endl; std::ifstream conserved{ C::path / config->get( "conserve_path" ) }; int cons; conserved >> cons; if( cons == 1 ) { conserveButton->value( 1 ); } else { conserveButton->value( 0 ); } if( C::debugUpdate ) std::cerr << "Conservation state read as: " << cons << std::endl; std::ifstream acCheck{ C::path / config->get( "power_path" ) / "online" }; int ac= -1; acCheck >> ac; acButton->value( ac ); if( C::debugUpdate ) std::cerr << "AC state read as: " << ac << std::endl; const auto backlightPercent= getBacklightPercent( config->get( "backlight_path" ) ); brightness->value( backlightPercent ); } int main( const int argcnt, char **argvec ) { config= std::make_unique< ConfigFile > ( ConfigFile { std::ifstream{ C::path / ::getenv( "HOME" ) / ".power_console.conf" }, { { "battery_path", C::defaultBatteryPath.string() }, { "power_path", C::defaultPowerPath.string() }, { "backlight_path", C::defaultBacklightPath.string() }, { "conserve_path", C::defaultConservePath.string() }, } } ); auto w= make_window(); level->minimum( 0 ); level->maximum( 100 ); level->value( 0 ); level->label( battLevelString.c_str() ); brightness->maximum( 0 ); brightness->minimum( 100 ); brightness->step( -1 ); w->hotspot( w ); w->show( argcnt, argvec ); conserveButton->callback((Fl_Callback*)consClicked); Fl::repeat_timeout( C::updateTimeout, scheduledUpdate, nullptr ); Fl::repeat_timeout( 0, profileUpdate, nullptr ); Fl::run(); } void consClicked( Fl_Light_Button *, void * ) { std::cerr << "Conserve!" << std::endl; std::ifstream oldConserved{ C::path / config->get( "conserve_path" ) }; int state; oldConserved >> state; const int newState= 1 - state; conserveButton->value( newState ); std::ofstream conserved{ C::path / config->get( "conserve_path" ) }; conserved << newState; std::cerr << "Tried to set new state to " << newState << std::endl; } void saverChosen() { setPowerMode( "power-saver" ); } void balChosen() { setPowerMode( "balanced" ); } void perfChosen() { setPowerMode( "performance" ); }