diff --git a/pyrainput.cpp b/pyrainput.cpp index 25a733a2c18cd9e8d3fb35a3f2752b6c8332ce6c..054a6c67b8173e87c17fdb10de37245dfa480b7a 100644 --- a/pyrainput.cpp +++ b/pyrainput.cpp @@ -105,15 +105,15 @@ struct Settings { LEFT_ALT, RIGHT_ALT }; - NubAxisMode leftNubModeX = MOUSE_X; - NubAxisMode leftNubModeY = MOUSE_Y; - NubAxisMode rightNubModeX = MOUSE_BTN; - NubAxisMode rightNubModeY = SCROLL_Y; - NubClickMode leftNubClickMode = MOUSE_LEFT; - NubClickMode rightNubClickMode = MOUSE_RIGHT; + std::vector leftNubModeX = { MOUSE_X }; + std::vector leftNubModeY = { MOUSE_Y }; + std::vector rightNubModeX = { MOUSE_BTN }; + std::vector rightNubModeY = { SCROLL_Y }; + std::vector leftNubClickMode = { MOUSE_LEFT }; + std::vector rightNubClickMode = { MOUSE_RIGHT }; - AltMode startButton = LEFT_ALT; - AltMode rightTrigger = RIGHT_ALT; + std::vector startButton = { LEFT_ALT }; + std::vector rightTrigger = { RIGHT_ALT }; // May be changed from any thread at any time int joyDeadzone = 10; @@ -165,6 +165,9 @@ void handleNubClick(Settings::NubClickMode mode, int value, Mouse* mouse, Uinput // Mouse movement/scroll thread handler void handleMouse(Mouse* mouse, Settings* settings, bool* stop); +// Parse whitespace separated list of items +template std::vector parseMultivalue(std::string const& str, std::function fn); + struct { bool stop = false; UinputDevice* gamepad = nullptr; @@ -321,14 +324,18 @@ void handle(input_event const& e, unsigned int role) { global.gamepad->send(EV_ABS, ABS_X, e.value); global.gamepad->send(EV_SYN, 0, 0); } - handleNubAxis(global.settings.leftNubModeX, e.value, global.mouse, global.gamepad, global.settings); + for(auto mode : global.settings.leftNubModeX) { + handleNubAxis(mode, e.value, global.mouse, global.gamepad, global.settings); + } break; case ABS_Y: if (global.settings.exportGamepad && (e.value>global.settings.joyDeadzone||e.value<-global.settings.joyDeadzone)) { global.gamepad->send(EV_ABS, ABS_Y, e.value); global.gamepad->send(EV_SYN, 0, 0); } - handleNubAxis(global.settings.leftNubModeY, e.value, global.mouse, global.gamepad, global.settings); + for(auto mode : global.settings.leftNubModeY) { + handleNubAxis(mode, e.value, global.mouse, global.gamepad, global.settings); + } break; default: break; }; @@ -339,14 +346,18 @@ void handle(input_event const& e, unsigned int role) { global.gamepad->send(EV_ABS, ABS_RX, e.value); global.gamepad->send(EV_SYN, 0, 0); } - handleNubAxis(global.settings.rightNubModeX, e.value, global.mouse, global.gamepad, global.settings); + for(auto mode : global.settings.rightNubModeX) { + handleNubAxis(mode, e.value, global.mouse, global.gamepad, global.settings); + } break; case ABS_Y: if (global.settings.exportGamepad && (e.value>global.settings.joyDeadzone||e.value<-global.settings.joyDeadzone)) { global.gamepad->send(EV_ABS, ABS_RY, e.value); global.gamepad->send(EV_SYN, 0, 0); } - handleNubAxis(global.settings.rightNubModeY, e.value, global.mouse, global.gamepad, global.settings); + for(auto mode : global.settings.rightNubModeY) { + handleNubAxis(mode, e.value, global.mouse, global.gamepad, global.settings); + } break; default: break; }; @@ -356,12 +367,16 @@ void handle(input_event const& e, unsigned int role) { switch(e.code) { case BTN_LEFT: // Right nub click if (role == ROLE_GPIO) { - handleNubClick(global.settings.rightNubClickMode, e.value, global.mouse, global.gamepad, global.settings); + for(auto mode : global.settings.rightNubClickMode) { + handleNubClick(mode, e.value, global.mouse, global.gamepad, global.settings); + } } break; case BTN_RIGHT: // Left nub click if (role == ROLE_GPIO) { - handleNubClick(global.settings.leftNubClickMode, e.value, global.mouse, global.gamepad, global.settings); + for(auto mode : global.settings.leftNubClickMode) { + handleNubClick(mode, e.value, global.mouse, global.gamepad, global.settings); + } } break; @@ -486,28 +501,28 @@ SettingHandlerMap const SETTING_HANDLERS = { settings.joyDeadzone = std::stoi(value); } }, { "nubs.left.x", [](std::string const& value, Settings& settings) { - settings.leftNubModeX = parseNubAxisMode(value); + settings.leftNubModeX = parseMultivalue(value, parseNubAxisMode); } }, { "nubs.left.y", [](std::string const& value, Settings& settings) { - settings.leftNubModeY = parseNubAxisMode(value); + settings.leftNubModeY = parseMultivalue(value, parseNubAxisMode); } }, { "nubs.right.x", [](std::string const& value, Settings& settings) { - settings.rightNubModeX = parseNubAxisMode(value); + settings.rightNubModeX = parseMultivalue(value, parseNubAxisMode); } }, { "nubs.right.y", [](std::string const& value, Settings& settings) { - settings.rightNubModeY = parseNubAxisMode(value); + settings.rightNubModeY = parseMultivalue(value, parseNubAxisMode); } }, { "nubs.left.click", [](std::string const& value, Settings& settings) { - settings.leftNubClickMode = parseNubClickMode(value); + settings.leftNubClickMode = parseMultivalue(value, parseNubClickMode); } }, { "nubs.right.click", [](std::string const& value, Settings& settings) { - settings.rightNubClickMode = parseNubClickMode(value); + settings.rightNubClickMode = parseMultivalue(value, parseNubClickMode); } }, { "altmode.start.button", [](std::string const& value, Settings& settings) { - settings.startButton = parseAltMode(value); + settings.startButton = parseMultivalue(value, parseAltMode); } }, { "altmode.right.trigger", [](std::string const& value, Settings& settings) { - settings.rightTrigger = parseAltMode(value); + settings.rightTrigger = parseMultivalue(value, parseAltMode); } } }; @@ -542,14 +557,18 @@ void loadConfig(std::string const& filename, Settings& settings) { } } /* Apply "Alt Keys" mapping configuration */ - if (settings.startButton == Settings::LEFT_ALT) + if (std::find(settings.startButton.begin(), settings.startButton.end(), Settings::LEFT_ALT) != settings.startButton.end()) { global.behaviors->gpmap2(KEY_LEFTALT, BTN_START, &global.Alt.left, &global.Alt); - else + } + if (std::find(settings.startButton.begin(), settings.startButton.end(), Settings::RIGHT_ALT) != settings.startButton.end()) { global.behaviors->gpmap2(KEY_RIGHTALT, BTN_START, &global.Alt.right, &global.Alt); - if (settings.rightTrigger == Settings::LEFT_ALT) + } + if (std::find(settings.rightTrigger.begin(), settings.rightTrigger.end(), Settings::LEFT_ALT) != settings.rightTrigger.end()) { global.behaviors->gpmap2(KEY_LEFTALT, BTN_TR2, &global.Alt.left, &global.Alt); - else + } + if (std::find(settings.rightTrigger.begin(), settings.rightTrigger.end(), Settings::RIGHT_ALT) != settings.rightTrigger.end()) { global.behaviors->gpmap2(KEY_RIGHTALT, BTN_TR2, &global.Alt.right, &global.Alt); + } } Settings::NubAxisMode parseNubAxisMode(std::string const& str) { @@ -714,6 +733,13 @@ void handleMouse(Mouse* mouse, Settings* settings, bool* stop) { delete mouse; } +template std::vector parseMultivalue(std::string const& str, std::function fn) { + std::istringstream stream(str); + std::vector values; + std::transform(std::istream_iterator(stream), std::istream_iterator(), std::back_inserter(values), fn); + return values; +} + template void KeyBehaviors::passthrough(unsigned int code) { behaviors.at(code - FIRST_KEY).type = KeyBehavior::PASSTHROUGH; }