mirror of
https://github.com/CalcProgrammer1/OpenRGB.git
synced 2026-01-03 12:47:51 -05:00
Clean up some of the CLI code and add option to load a profile from the command line
This commit is contained in:
400
cli.cpp
400
cli.cpp
@@ -4,10 +4,12 @@
|
||||
#include <tuple>
|
||||
#include <iostream>
|
||||
#include "OpenRGB.h"
|
||||
#include "ProfileManager.h"
|
||||
#include "RGBController.h"
|
||||
#include "i2c_smbus.h"
|
||||
|
||||
static std::vector<RGBController*> 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<RGBController *> rgb_controllers_in)
|
||||
int cli_main(int argc, char *argv[], std::vector<RGBController *> 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")))
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user