diff --git a/src/gmenu2x.cpp b/src/gmenu2x.cpp index 9f13998..1473e42 100644 --- a/src/gmenu2x.cpp +++ b/src/gmenu2x.cpp @@ -265,12 +265,10 @@ GMenu2X::GMenu2X() DEBUG("Loading system input.conf file: %s.\n", input_file.c_str()); } - input.init(input_file, menu.get()); + input.init(this, input_file, menu.get()); if (confInt["backlightTimeout"] > 0) PowerSaver::getInstance()->setScreenTimeout( confInt["backlightTimeout"] ); - - SDL_EnableKeyRepeat(INPUT_KEY_REPEAT_DELAY, INPUT_KEY_REPEAT_RATE); #ifdef ENABLE_CPUFREQ setClock(confInt["menuClock"]); #endif @@ -498,6 +496,7 @@ void GMenu2X::readConfig(string conffile) { cpuFreqMenuDefault, cpuFreqMin, cpuFreqSafeMax ); #endif evalIntConf( confInt, "backlightTimeout", 15, 0,120 ); + evalIntConf( confInt, "buttonRepeatRate", 10, 0, 20 ); evalIntConf( confInt, "videoBpp", 32, 16, 32 ); if (confStr["tvoutEncoding"] != "PAL") confStr["tvoutEncoding"] = "NTSC"; @@ -736,6 +735,7 @@ void GMenu2X::showSettings() { #endif sd.addSetting(new MenuSettingBool(this, ts, tr["Output logs"], tr["Logs the output of the links. Use the Log Viewer to read them."], &confInt["outputLogs"])); sd.addSetting(new MenuSettingInt(this, ts, tr["Screen Timeout"], tr["Set screen's backlight timeout in seconds"], &confInt["backlightTimeout"], 0, 120)); + sd.addSetting(new MenuSettingInt(this, ts, tr["Button repeat rate"], tr["Set button repetitions per second"], &confInt["buttonRepeatRate"], 0, 20)); if (sd.exec() && sd.edited()) { #ifdef ENABLE_CPUFREQ @@ -749,6 +749,8 @@ void GMenu2X::showSettings() { PowerSaver::getInstance()->setScreenTimeout( confInt["backlightTimeout"] ); } + input.repeatRateChanged(); + if (lang == "English") lang = ""; if (lang != tr.lang()) { tr.setLang(lang); diff --git a/src/inputmanager.cpp b/src/inputmanager.cpp index 2517eb5..cf35cf8 100644 --- a/src/inputmanager.cpp +++ b/src/inputmanager.cpp @@ -20,6 +20,7 @@ #include "debug.h" #include "inputmanager.h" +#include "gmenu2x.h" #include "utilities.h" #include "powersaver.h" #include "menu.h" @@ -29,9 +30,12 @@ using namespace std; -void InputManager::init(const string &conffile, Menu *menu) { +void InputManager::init(GMenu2X *gmenu2x, const string &conffile, Menu *menu) { + this->gmenu2x = gmenu2x; this->menu = menu; + repeatRateChanged(); + for (int i = 0; i < BUTTON_TYPE_SIZE; i++) { buttonMap[i].js_mapped = false; buttonMap[i].kb_mapped = false; @@ -52,7 +56,7 @@ InputManager::InputManager() for (i = 0; i < SDL_NumJoysticks(); i++) { struct Joystick joystick = { SDL_JoystickOpen(i), false, false, false, false, - SDL_HAT_CENTERED, nullptr, + SDL_HAT_CENTERED, nullptr, this, }; joysticks.push_back(joystick); } @@ -127,6 +131,20 @@ InputManager::Button InputManager::waitForPressedButton() { return button; } +static int repeatRateMs(int repeatRate) +{ + return repeatRate == 0 ? 0 : 1000 / repeatRate; +} + +void InputManager::repeatRateChanged() { + int ms = repeatRateMs(gmenu2x->confInt["buttonRepeatRate"]); + if (ms == 0) { + SDL_EnableKeyRepeat(0, 0); + } else { + SDL_EnableKeyRepeat(INPUT_KEY_REPEAT_DELAY, ms); + } +} + bool InputManager::pollButton(Button *button) { return getButton(button, false); } @@ -276,9 +294,23 @@ bool InputManager::getButton(Button *button, bool wait) { return true; } -Uint32 keyRepeatCallback(Uint32 timeout __attribute__((unused)), void *d) +Uint32 keyRepeatCallback(Uint32 timeout, void *d) { struct Joystick *joystick = (struct Joystick *) d; + return joystick->inputManager->joystickRepeatCallback(timeout, joystick); +} + +void InputManager::startTimer(Joystick *joystick) +{ + if (joystick->timer) + return; + + joystick->timer = SDL_AddTimer(INPUT_KEY_REPEAT_DELAY, + keyRepeatCallback, joystick); +} + +Uint32 InputManager::joystickRepeatCallback(Uint32 timeout __attribute__((unused)), struct Joystick *joystick) +{ Uint8 hatState; if (joystick->axisState[1][AXIS_STATE_NEGATIVE]) @@ -300,16 +332,7 @@ Uint32 keyRepeatCallback(Uint32 timeout __attribute__((unused)), void *d) }; SDL_PushEvent((SDL_Event *) &e); - return INPUT_KEY_REPEAT_RATE; -} - -void InputManager::startTimer(Joystick *joystick) -{ - if (joystick->timer) - return; - - joystick->timer = SDL_AddTimer(INPUT_KEY_REPEAT_DELAY, - keyRepeatCallback, joystick); + return repeatRateMs(gmenu2x->confInt["buttonRepeatRate"]); } void InputManager::stopTimer(Joystick *joystick) diff --git a/src/inputmanager.h b/src/inputmanager.h index bcab674..7763d07 100644 --- a/src/inputmanager.h +++ b/src/inputmanager.h @@ -26,9 +26,10 @@ #include #define INPUT_KEY_REPEAT_DELAY 250 -#define INPUT_KEY_REPEAT_RATE 150 +class GMenu2X; class Menu; +class InputManager; enum EventCode { REMOVE_LINKS, @@ -45,6 +46,7 @@ struct Joystick { bool axisState[2][2]; Uint8 hatState; SDL_TimerID timer; + InputManager *inputManager; }; #endif @@ -62,8 +64,10 @@ public: InputManager(); ~InputManager(); - void init(const std::string &conffile, Menu *menu); + void init(GMenu2X *gmenu2x, const std::string &conffile, Menu *menu); Button waitForPressedButton(); + void repeatRateChanged(); + Uint32 joystickRepeatCallback(Uint32 timeout, struct Joystick *joystick); bool pollButton(Button *button); bool getButton(Button *button, bool wait); @@ -75,6 +79,7 @@ private: unsigned int kb_code, js_code; }; + GMenu2X *gmenu2x; Menu *menu; ButtonMapEntry buttonMap[BUTTON_TYPE_SIZE];