Date:2014-06-18 23:12:11 (3 months 3 days ago)
Author:Nebuleon Fumika
Commit:9c4e97c83946342dde323c5892c03892952fdb5d
Message: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.
Files: src/gmenu2x.cpp (4 diffs)
src/inputmanager.cpp (6 diffs)
src/inputmanager.h (4 diffs)

Change Details

src/gmenu2x.cpp
265265        DEBUG("Loading system input.conf file: %s.\n", input_file.c_str());
266266    }
267267
268    input.init(input_file, menu.get());
268    input.init(this, input_file, menu.get());
269269
270270    if (confInt["backlightTimeout"] > 0)
271271        PowerSaver::getInstance()->setScreenTimeout( confInt["backlightTimeout"] );
272
273    SDL_EnableKeyRepeat(INPUT_KEY_REPEAT_DELAY, INPUT_KEY_REPEAT_RATE);
274272#ifdef ENABLE_CPUFREQ
275273    setClock(confInt["menuClock"]);
276274#endif
...... 
498496                 cpuFreqMenuDefault, cpuFreqMin, cpuFreqSafeMax );
499497#endif
500498    evalIntConf( confInt, "backlightTimeout", 15, 0,120 );
499    evalIntConf( confInt, "buttonRepeatRate", 10, 0, 20 );
501500    evalIntConf( confInt, "videoBpp", 32, 16, 32 );
502501
503502    if (confStr["tvoutEncoding"] != "PAL") confStr["tvoutEncoding"] = "NTSC";
...... 
736735#endif
737736    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"]));
738737    sd.addSetting(new MenuSettingInt(this, ts, tr["Screen Timeout"], tr["Set screen's backlight timeout in seconds"], &confInt["backlightTimeout"], 0, 120));
738    sd.addSetting(new MenuSettingInt(this, ts, tr["Button repeat rate"], tr["Set button repetitions per second"], &confInt["buttonRepeatRate"], 0, 20));
739739
740740    if (sd.exec() && sd.edited()) {
741741#ifdef ENABLE_CPUFREQ
...... 
749749            PowerSaver::getInstance()->setScreenTimeout( confInt["backlightTimeout"] );
750750        }
751751
752        input.repeatRateChanged();
753
752754        if (lang == "English") lang = "";
753755        if (lang != tr.lang()) {
754756            tr.setLang(lang);
src/inputmanager.cpp
2020
2121#include "debug.h"
2222#include "inputmanager.h"
23#include "gmenu2x.h"
2324#include "utilities.h"
2425#include "powersaver.h"
2526#include "menu.h"
...... 
2930
3031using namespace std;
3132
32void InputManager::init(const string &conffile, Menu *menu) {
33void InputManager::init(GMenu2X *gmenu2x, const string &conffile, Menu *menu) {
34    this->gmenu2x = gmenu2x;
3335    this->menu = menu;
3436
37    repeatRateChanged();
38
3539    for (int i = 0; i < BUTTON_TYPE_SIZE; i++) {
3640        buttonMap[i].js_mapped = false;
3741        buttonMap[i].kb_mapped = false;
...... 
5256    for (i = 0; i < SDL_NumJoysticks(); i++) {
5357        struct Joystick joystick = {
5458            SDL_JoystickOpen(i), false, false, false, false,
55            SDL_HAT_CENTERED, nullptr,
59            SDL_HAT_CENTERED, nullptr, this,
5660        };
5761        joysticks.push_back(joystick);
5862    }
...... 
127131    return button;
128132}
129133
134static int repeatRateMs(int repeatRate)
135{
136    return repeatRate == 0 ? 0 : 1000 / repeatRate;
137}
138
139void InputManager::repeatRateChanged() {
140    int ms = repeatRateMs(gmenu2x->confInt["buttonRepeatRate"]);
141    if (ms == 0) {
142        SDL_EnableKeyRepeat(0, 0);
143    } else {
144        SDL_EnableKeyRepeat(INPUT_KEY_REPEAT_DELAY, ms);
145    }
146}
147
130148bool InputManager::pollButton(Button *button) {
131149    return getButton(button, false);
132150}
...... 
276294    return true;
277295}
278296
279Uint32 keyRepeatCallback(Uint32 timeout __attribute__((unused)), void *d)
297Uint32 keyRepeatCallback(Uint32 timeout, void *d)
280298{
281299    struct Joystick *joystick = (struct Joystick *) d;
300    return joystick->inputManager->joystickRepeatCallback(timeout, joystick);
301}
302
303void InputManager::startTimer(Joystick *joystick)
304{
305    if (joystick->timer)
306        return;
307
308    joystick->timer = SDL_AddTimer(INPUT_KEY_REPEAT_DELAY,
309                keyRepeatCallback, joystick);
310}
311
312Uint32 InputManager::joystickRepeatCallback(Uint32 timeout __attribute__((unused)), struct Joystick *joystick)
313{
282314    Uint8 hatState;
283315
284316    if (joystick->axisState[1][AXIS_STATE_NEGATIVE])
...... 
300332    };
301333    SDL_PushEvent((SDL_Event *) &e);
302334
303    return INPUT_KEY_REPEAT_RATE;
304}
305
306void InputManager::startTimer(Joystick *joystick)
307{
308    if (joystick->timer)
309        return;
310
311    joystick->timer = SDL_AddTimer(INPUT_KEY_REPEAT_DELAY,
312                keyRepeatCallback, joystick);
335    return repeatRateMs(gmenu2x->confInt["buttonRepeatRate"]);
313336}
314337
315338void InputManager::stopTimer(Joystick *joystick)
src/inputmanager.h
2626#include <vector>
2727
2828#define INPUT_KEY_REPEAT_DELAY 250
29#define INPUT_KEY_REPEAT_RATE 150
3029
30class GMenu2X;
3131class Menu;
32class InputManager;
3233
3334enum EventCode {
3435    REMOVE_LINKS,
...... 
4546    bool axisState[2][2];
4647    Uint8 hatState;
4748    SDL_TimerID timer;
49    InputManager *inputManager;
4850};
4951#endif
5052
...... 
6264    InputManager();
6365    ~InputManager();
6466
65    void init(const std::string &conffile, Menu *menu);
67    void init(GMenu2X *gmenu2x, const std::string &conffile, Menu *menu);
6668    Button waitForPressedButton();
69    void repeatRateChanged();
70    Uint32 joystickRepeatCallback(Uint32 timeout, struct Joystick *joystick);
6771    bool pollButton(Button *button);
6872    bool getButton(Button *button, bool wait);
6973
...... 
7579        unsigned int kb_code, js_code;
7680    };
7781
82    GMenu2X *gmenu2x;
7883    Menu *menu;
7984
8085    ButtonMapEntry buttonMap[BUTTON_TYPE_SIZE];

Archive Download the corresponding diff file



interactive