diff --git a/OpenRGB.cpp b/OpenRGB.cpp index 5f4bf72f..b26b4f31 100644 --- a/OpenRGB.cpp +++ b/OpenRGB.cpp @@ -312,7 +312,7 @@ void DetectRGBFusion2USBControllers(std::vector &rgb_controllers * Detect and populate RGB Controllers vector * * * \******************************************************************************************/ -#include "RGBController_Dummy.h" + void DetectRGBControllers(void) { DetectI2CBusses(); diff --git a/cli.cpp b/cli.cpp index d7d314b6..e7d5384d 100644 --- a/cli.cpp +++ b/cli.cpp @@ -4,10 +4,12 @@ #include #include #include "OpenRGB.h" +#include "ProfileManager.h" #include "RGBController.h" #include "i2c_smbus.h" static std::vector rgb_controllers; +static ProfileManager* profile_manager; struct DeviceOptions { @@ -34,15 +36,17 @@ void PrintHelp() help_text += VERSION_STRING; help_text += ", for controlling RGB lighting.\n"; help_text += "Usage: OpenRGB (--device [--mode] [--color])...\n"; - help_text += "\nOptions:\n"; - help_text += "--gui\t\t\t\t\t Show GUI, also appears when not passing any parameters\n"; - help_text += "-l, --list-devices\t\t\t Lists every compatible device with their number\n"; - help_text += "-d, --device [0-9]\t\t\t Selects device to apply colors and/or effect to, or applies to all devices if omitted\n"; - help_text += "\t\t\t\t\t Can be specified multiple times with different modes and colors\n"; - help_text += "-c, --color \"FFFFFF,00AAFF...\"\t\t Sets colors on each device directly if no effect is specified, and sets the effect color if an effect is specified\n"; - help_text += "\t\t\t\t\t If there are more LEDs than colors given, the last color will be applied to the remaining LEDs\n"; + help_text += "\n"; + help_text += "Options:\n"; + help_text += "--gui Show GUI, also appears when not passing any parameters\n"; + help_text += "-l, --list-devices Lists every compatible device with their number\n"; + help_text += "-d, --device [0-9] Selects device to apply colors and/or effect to, or applies to all devices if omitted\n"; + help_text += " Can be specified multiple times with different modes and colors\n"; + help_text += "-c, --color \"FFFFFF,00AAFF...\" Sets colors on each device directly if no effect is specified, and sets the effect color if an effect is specified\n"; + help_text += " If there are more LEDs than colors given, the last color will be applied to the remaining LEDs\n"; help_text += "-m, --mode [breathing | static | ...] Sets the mode to be applied, check --list-devices to see which modes are supported on your device\n"; - help_text += "-v, --version\t\t\t\t Display version and software build information\n"; + help_text += "-v, --version Display version and software build information\n"; + help_text += "-p, --profile filename.orp Load the profile from filename.orp\n"; std::cout << help_text << std::endl; } @@ -147,144 +151,283 @@ std::string QuoteIfNecessary(std::string str) } } +/*---------------------------------------------------------------------------------------------------------*\ +| Option processing functions | +\*---------------------------------------------------------------------------------------------------------*/ + +void OptionListDevices() +{ + for(std::size_t controller_idx = 0; controller_idx < rgb_controllers.size(); controller_idx++) + { + RGBController *controller = rgb_controllers[controller_idx]; + + /*---------------------------------------------------------*\ + | Print device name | + \*---------------------------------------------------------*/ + std::cout << controller_idx << ": " << controller->name << std::endl; + + /*---------------------------------------------------------*\ + | Print device type | + \*---------------------------------------------------------*/ + std::cout << " Type: " << device_type_to_str(controller->type) << std::endl; + + /*---------------------------------------------------------*\ + | Print device description | + \*---------------------------------------------------------*/ + if(!controller->description.empty()) + { + std::cout << " Description: " << controller->description << std::endl; + } + + /*---------------------------------------------------------*\ + | Print device version | + \*---------------------------------------------------------*/ + if(!controller->version.empty()) + { + std::cout << " Version: " << controller->version << std::endl; + } + + /*---------------------------------------------------------*\ + | Print device location | + \*---------------------------------------------------------*/ + if(!controller->location.empty()) + { + std::cout << " Location: " << controller->location << std::endl; + } + + /*---------------------------------------------------------*\ + | Print device serial | + \*---------------------------------------------------------*/ + if(!controller->serial.empty()) + { + std::cout << " Serial: " << controller->serial << std::endl; + } + + /*---------------------------------------------------------*\ + | Print device modes | + \*---------------------------------------------------------*/ + if(!controller->modes.empty()) + { + std::cout << " Modes:"; + + int current_mode = controller->GetMode(); + for(std::size_t mode_idx = 0; mode_idx < controller->modes.size(); mode_idx++) + { + std::string modeStr = QuoteIfNecessary(controller->modes[mode_idx].name); + + if(current_mode == (int)mode_idx) + { + modeStr = "[" + modeStr + "]"; + } + std::cout << " " << modeStr; + } + std::cout << std::endl; + } + + /*---------------------------------------------------------*\ + | Print device zones | + \*---------------------------------------------------------*/ + if(!controller->zones.empty()) + { + std::cout << " Zones:"; + + for(std::size_t zone_idx = 0; zone_idx < controller->zones.size(); zone_idx++) + { + std::cout << " " << QuoteIfNecessary(controller->zones[zone_idx].name); + } + std::cout << std::endl; + } + + /*---------------------------------------------------------*\ + | Print device LEDs | + \*---------------------------------------------------------*/ + if(!controller->leds.empty()) + { + std::cout << " LEDs:"; + + for(std::size_t led_idx = 0; led_idx < controller->leds.size(); led_idx++) + { + std::cout << " " << QuoteIfNecessary(controller->leds[led_idx].name); + } + std::cout << std::endl; + } + + std::cout << std::endl; + } +} + +bool OptionDevice(int currentDev, std::string argument, Options *res) +{ + try + { + currentDev = std::stoi(argument); + + if (rgb_controllers.size() <= currentDev || currentDev < 0) + { + throw; + } + + DeviceOptions newDev; + newDev.device = currentDev; + + if(!res->hasDevice) + { + res->hasDevice = true; + } + + res->devices.push_back(newDev); + + return true; + } + catch(...) + { + std::cout << "Error: Invalid device ID: " + argument << std::endl; + return false; + } +} + +bool OptionColor(int currentDev, std::string argument, Options *res) +{ + DeviceOptions* currentDevOpts = GetDeviceOptionsForDevID(res, currentDev); + + if(ParseColors(argument, currentDevOpts)) + { + currentDevOpts->hasOption = true; + } + else + { + std::cout << "Error: Invalid color value: " + argument << std::endl; + return false; + } +} + +bool OptionMode(int currentDev, std::string argument, Options *res) +{ + DeviceOptions* currentDevOpts = GetDeviceOptionsForDevID(res, currentDev); + currentDevOpts->mode = argument; + currentDevOpts->hasOption = true; + return true; +} + +bool OptionProfile(int currentDev, std::string argument, Options *res) +{ + /*---------------------------------------------------------*\ + | Attempt to load profile | + \*---------------------------------------------------------*/ + if(profile_manager->LoadProfile(argument)) + { + /*-----------------------------------------------------*\ + | Change device mode if profile loading was successful | + \*-----------------------------------------------------*/ + for(std::size_t controller_idx = 0; controller_idx < rgb_controllers.size(); controller_idx++) + { + RGBController* device = rgb_controllers[controller_idx]; + + device->SetMode(device->active_mode); + + if(device->modes[device->active_mode].color_mode == MODE_COLORS_PER_LED) + { + device->UpdateLEDs(); + } + } + + std::cout << "Profile loaded successfully" << std::endl; + return true; + } + else + { + std::cout << "Profile failed to load" << std::endl; + return false; + } +} + bool ProcessOptions(int argc, char *argv[], Options *res) { int arg_index = 1; int currentDev = -1; - while (arg_index < argc) + while(arg_index < argc) { - std::string option = argv[arg_index]; + std::string option = argv[arg_index]; + std::string argument = ""; - // Handle options that take no arguments - if (option == "--list-devices" || option == "-l") + /*---------------------------------------------------------*\ + | Handle options that take an argument | + \*---------------------------------------------------------*/ + if(arg_index + 1 < argc) { - for (int i = 0; i < rgb_controllers.size(); i++) - { - RGBController *c = rgb_controllers[i]; - std::cout << i << ": " << c->name << std::endl; - - std::cout << " Type: " << device_type_to_str(c->type) << std::endl; - - if (!c->serial.empty()) - { - std::cout << " Serial: " << c->serial << std::endl; - } - - if (!c->description.empty()) - { - std::cout << " Description: " << c->description << std::endl; - } - - if (!c->modes.empty()) - { - std::cout << " Modes:"; - int curMode = c->GetMode(); - for (int i = 0; i < c->modes.size(); i++) - { - std::string modeStr = QuoteIfNecessary(c->modes[i].name); - if (curMode == i) { - modeStr = "[" + modeStr + "]"; - } - std::cout << " " << modeStr; - } - std::cout << std::endl; - } - - if (!c->zones.empty()) - { - std::cout << " Zones:"; - for (int i = 0; i < c->zones.size(); i++) - { - std::cout << " " << QuoteIfNecessary(c->zones[i].name); - } - std::cout << std::endl; - } - - if (!c->leds.empty()) - { - std::cout << " LEDs:"; - for (int i = 0; i < c->leds.size(); i++) - { - std::cout << " " << QuoteIfNecessary(c->leds[i].name); - } - std::cout << std::endl; - } - - std::cout << std::endl; - } - exit(0); - } - else if (arg_index + 1 < argc) // Handle options that take an argument - { - std::string argument = argv[arg_index + 1]; - - if (option == "--device" || option == "-d") - { - try - { - currentDev = std::stoi(argument); - - if (rgb_controllers.size() <= currentDev || currentDev < 0) - { - throw; - } - - DeviceOptions newDev; - newDev.device = currentDev; - - if (!res->hasDevice) - { - res->hasDevice = true; - } - - res->devices.push_back(newDev); - } - catch (...) - { - std::cout << "Error: Invalid device ID: " + argument << std::endl; - return false; - } - } - else if (option == "--color" || option == "-c") - { - DeviceOptions* currentDevOpts = GetDeviceOptionsForDevID(res, currentDev); - if (ParseColors(argument, currentDevOpts)) - { - currentDevOpts->hasOption = true; - } - else - { - std::cout << "Error: Invalid argument to " + option + ": " + argument << std::endl; - return false; - } - } - else if (option == "--mode" || option == "-m") - { - DeviceOptions* currentDevOpts = GetDeviceOptionsForDevID(res, currentDev); - currentDevOpts->mode = argument; - currentDevOpts->hasOption = true; - } - else - { - std::cout << "Error: Invalid option: " + option << std::endl; - return false; - } - + argument = argv[arg_index + 1]; arg_index++; } + + /*---------------------------------------------------------*\ + | -l / --list-devices | + \*---------------------------------------------------------*/ + if(option == "--list-devices" || option == "-l") + { + OptionListDevices(); + exit(0); + } + + /*---------------------------------------------------------*\ + | -d / --device | + \*---------------------------------------------------------*/ + else if(option == "--device" || option == "-d") + { + if(!OptionDevice(currentDev, argument, res)) + { + return false; + } + } + + /*---------------------------------------------------------*\ + | -c / --color | + \*---------------------------------------------------------*/ + else if(option == "--color" || option == "-c") + { + if(!OptionColor(currentDev, argument, res)) + { + return false; + } + } + + /*---------------------------------------------------------*\ + | -m / --mode | + \*---------------------------------------------------------*/ + else if(option == "--mode" || option == "-m") + { + if(!OptionMode(currentDev, argument, res)) + { + return false; + } + } + + /*---------------------------------------------------------*\ + | -p / --profile | + \*---------------------------------------------------------*/ + else if(option == "--profile" || option == "-p") + { + OptionProfile(currentDev, argument, res); + exit(0); + } + + /*---------------------------------------------------------*\ + | Invalid option | + \*---------------------------------------------------------*/ else { + std::cout << "Error: Invalid option: " + option << std::endl; return false; } + arg_index++; } - if (res->hasDevice) + if(res->hasDevice) { - for (int i = 0; i < res->devices.size(); i++) + for(int i = 0; i < res->devices.size(); i++) { - if (!res->devices[i].hasOption) + if(!res->devices[i].hasOption) { std::cout << "Error: Device " + std::to_string(i) + " specified, but neither mode nor color given" << std::endl; return false; @@ -324,9 +467,10 @@ void ApplyOptions(DeviceOptions& options) } } -int cli_main(int argc, char *argv[], std::vector rgb_controllers_in) +int cli_main(int argc, char *argv[], std::vector rgb_controllers_in, ProfileManager* profile_manager_in) { rgb_controllers = rgb_controllers_in; + profile_manager = profile_manager_in; if (argc == 2 && (!strcmp(argv[1], "--help") || !strcmp(argv[1], "-h"))) { diff --git a/main.cpp b/main.cpp index 21381cb0..f12b12a0 100644 --- a/main.cpp +++ b/main.cpp @@ -21,7 +21,7 @@ extern std::vector busses; extern std::vector rgb_controllers; // See cli.cpp -extern int cli_main(int argc, char *argv[], std::vector rgb_controllers_in); +extern int cli_main(int argc, char *argv[], std::vector rgb_controllers_in, ProfileManager* profile_manager_in); /******************************************************************************************\ * * @@ -41,7 +41,7 @@ int main(int argc, char* argv[]) if (argc > 1 && strcmp(argv[1], "--gui")) { - return cli_main(argc, argv, rgb_controllers); + return cli_main(argc, argv, rgb_controllers, &profile_manager); } QApplication::setAttribute(Qt::AA_EnableHighDpiScaling);