1
0
mirror of git://projects.qi-hardware.com/gmenu2x.git synced 2024-11-22 11:46:14 +02:00

Make the button repeat rate (after the first repetition) a user setting.

This allows for faster scrolling between section links, in file and directory
selectors, and in manuals, without repeatedly pressing buttons.

The setting's unit is repetitions per second. Its default value is set to
10, and anything between 0 (disabled) and 20 (50 ms) is acceptable.

Grabbing &(instance of GMenu2X).confInt["buttonRepeatRate"] is unsafe, because
the storage for the slot may move as the slot is deleted or added. Instead, a
callback jumps back into the context of an InputManager so the value can be
read from a GMenu2X object's configuration.

A GMenu2X object is also passed to InputManager::init.
This commit is contained in:
Nebuleon Fumika 2014-06-18 21:12:11 +00:00 committed by Maarten ter Huurne
parent 98a63e2940
commit 9c4e97c839
3 changed files with 48 additions and 18 deletions

View File

@ -265,12 +265,10 @@ GMenu2X::GMenu2X()
DEBUG("Loading system input.conf file: %s.\n", input_file.c_str()); 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) if (confInt["backlightTimeout"] > 0)
PowerSaver::getInstance()->setScreenTimeout( confInt["backlightTimeout"] ); PowerSaver::getInstance()->setScreenTimeout( confInt["backlightTimeout"] );
SDL_EnableKeyRepeat(INPUT_KEY_REPEAT_DELAY, INPUT_KEY_REPEAT_RATE);
#ifdef ENABLE_CPUFREQ #ifdef ENABLE_CPUFREQ
setClock(confInt["menuClock"]); setClock(confInt["menuClock"]);
#endif #endif
@ -498,6 +496,7 @@ void GMenu2X::readConfig(string conffile) {
cpuFreqMenuDefault, cpuFreqMin, cpuFreqSafeMax ); cpuFreqMenuDefault, cpuFreqMin, cpuFreqSafeMax );
#endif #endif
evalIntConf( confInt, "backlightTimeout", 15, 0,120 ); evalIntConf( confInt, "backlightTimeout", 15, 0,120 );
evalIntConf( confInt, "buttonRepeatRate", 10, 0, 20 );
evalIntConf( confInt, "videoBpp", 32, 16, 32 ); evalIntConf( confInt, "videoBpp", 32, 16, 32 );
if (confStr["tvoutEncoding"] != "PAL") confStr["tvoutEncoding"] = "NTSC"; if (confStr["tvoutEncoding"] != "PAL") confStr["tvoutEncoding"] = "NTSC";
@ -736,6 +735,7 @@ void GMenu2X::showSettings() {
#endif #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 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["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()) { if (sd.exec() && sd.edited()) {
#ifdef ENABLE_CPUFREQ #ifdef ENABLE_CPUFREQ
@ -749,6 +749,8 @@ void GMenu2X::showSettings() {
PowerSaver::getInstance()->setScreenTimeout( confInt["backlightTimeout"] ); PowerSaver::getInstance()->setScreenTimeout( confInt["backlightTimeout"] );
} }
input.repeatRateChanged();
if (lang == "English") lang = ""; if (lang == "English") lang = "";
if (lang != tr.lang()) { if (lang != tr.lang()) {
tr.setLang(lang); tr.setLang(lang);

View File

@ -20,6 +20,7 @@
#include "debug.h" #include "debug.h"
#include "inputmanager.h" #include "inputmanager.h"
#include "gmenu2x.h"
#include "utilities.h" #include "utilities.h"
#include "powersaver.h" #include "powersaver.h"
#include "menu.h" #include "menu.h"
@ -29,9 +30,12 @@
using namespace std; 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; this->menu = menu;
repeatRateChanged();
for (int i = 0; i < BUTTON_TYPE_SIZE; i++) { for (int i = 0; i < BUTTON_TYPE_SIZE; i++) {
buttonMap[i].js_mapped = false; buttonMap[i].js_mapped = false;
buttonMap[i].kb_mapped = false; buttonMap[i].kb_mapped = false;
@ -52,7 +56,7 @@ InputManager::InputManager()
for (i = 0; i < SDL_NumJoysticks(); i++) { for (i = 0; i < SDL_NumJoysticks(); i++) {
struct Joystick joystick = { struct Joystick joystick = {
SDL_JoystickOpen(i), false, false, false, false, SDL_JoystickOpen(i), false, false, false, false,
SDL_HAT_CENTERED, nullptr, SDL_HAT_CENTERED, nullptr, this,
}; };
joysticks.push_back(joystick); joysticks.push_back(joystick);
} }
@ -127,6 +131,20 @@ InputManager::Button InputManager::waitForPressedButton() {
return button; 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) { bool InputManager::pollButton(Button *button) {
return getButton(button, false); return getButton(button, false);
} }
@ -276,9 +294,23 @@ bool InputManager::getButton(Button *button, bool wait) {
return true; return true;
} }
Uint32 keyRepeatCallback(Uint32 timeout __attribute__((unused)), void *d) Uint32 keyRepeatCallback(Uint32 timeout, void *d)
{ {
struct Joystick *joystick = (struct Joystick *) 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; Uint8 hatState;
if (joystick->axisState[1][AXIS_STATE_NEGATIVE]) if (joystick->axisState[1][AXIS_STATE_NEGATIVE])
@ -300,16 +332,7 @@ Uint32 keyRepeatCallback(Uint32 timeout __attribute__((unused)), void *d)
}; };
SDL_PushEvent((SDL_Event *) &e); SDL_PushEvent((SDL_Event *) &e);
return INPUT_KEY_REPEAT_RATE; return repeatRateMs(gmenu2x->confInt["buttonRepeatRate"]);
}
void InputManager::startTimer(Joystick *joystick)
{
if (joystick->timer)
return;
joystick->timer = SDL_AddTimer(INPUT_KEY_REPEAT_DELAY,
keyRepeatCallback, joystick);
} }
void InputManager::stopTimer(Joystick *joystick) void InputManager::stopTimer(Joystick *joystick)

View File

@ -26,9 +26,10 @@
#include <vector> #include <vector>
#define INPUT_KEY_REPEAT_DELAY 250 #define INPUT_KEY_REPEAT_DELAY 250
#define INPUT_KEY_REPEAT_RATE 150
class GMenu2X;
class Menu; class Menu;
class InputManager;
enum EventCode { enum EventCode {
REMOVE_LINKS, REMOVE_LINKS,
@ -45,6 +46,7 @@ struct Joystick {
bool axisState[2][2]; bool axisState[2][2];
Uint8 hatState; Uint8 hatState;
SDL_TimerID timer; SDL_TimerID timer;
InputManager *inputManager;
}; };
#endif #endif
@ -62,8 +64,10 @@ public:
InputManager(); InputManager();
~InputManager(); ~InputManager();
void init(const std::string &conffile, Menu *menu); void init(GMenu2X *gmenu2x, const std::string &conffile, Menu *menu);
Button waitForPressedButton(); Button waitForPressedButton();
void repeatRateChanged();
Uint32 joystickRepeatCallback(Uint32 timeout, struct Joystick *joystick);
bool pollButton(Button *button); bool pollButton(Button *button);
bool getButton(Button *button, bool wait); bool getButton(Button *button, bool wait);
@ -75,6 +79,7 @@ private:
unsigned int kb_code, js_code; unsigned int kb_code, js_code;
}; };
GMenu2X *gmenu2x;
Menu *menu; Menu *menu;
ButtonMapEntry buttonMap[BUTTON_TYPE_SIZE]; ButtonMapEntry buttonMap[BUTTON_TYPE_SIZE];