Ticket #8532: keyboard-repeat3.diff

File keyboard-repeat3.diff, 18.7 KB (added by eriktorbjorn, 17 years ago)

Updated patch for the new event manager.

  • gui/newgui.cpp

     
    5050
    5151enum {
    5252        kDoubleClickDelay = 500, // milliseconds
    53         kCursorAnimateDelay = 250,
    54         kKeyRepeatInitialDelay = 400,
    55         kKeyRepeatSustainDelay = 100
     53        kCursorAnimateDelay = 250
    5654};
    5755
    5856void GuiObject::reflowLayout() {
     
    9189        // Clear the cursor
    9290        memset(_cursor, 0xFF, sizeof(_cursor));
    9391
    94         // Reset key repeat
    95         _currentKeyDown.keycode = 0;
    96 
    9792        bool loadClassicTheme = true;
    9893#ifndef DISABLE_FANCY_THEMES
    9994        ConfMan.registerDefault("gui_theme", "default");
     
    272267                       
    273268                        switch (event.type) {
    274269                        case OSystem::EVENT_KEYDOWN:
    275 #if !defined(PALMOS_MODE)
    276                                 // init continuous event stream
    277                                 // not done on PalmOS because keyboard is emulated and keyup is not generated
    278                                 _currentKeyDown.ascii = event.kbd.ascii;
    279                                 _currentKeyDown.keycode = event.kbd.keycode;
    280                                 _currentKeyDown.flags = event.kbd.flags;
    281                                 _keyRepeatTime = time + kKeyRepeatInitialDelay;
    282 #endif
    283270                                activeDialog->handleKeyDown(event.kbd.ascii, event.kbd.keycode, event.kbd.flags);
    284271                                break;
    285272                        case OSystem::EVENT_KEYUP:
    286273                                activeDialog->handleKeyUp(event.kbd.ascii, event.kbd.keycode, event.kbd.flags);
    287                                 if (event.kbd.keycode == _currentKeyDown.keycode)
    288                                         // only stop firing events if it's the current key
    289                                         _currentKeyDown.keycode = 0;
    290274                                break;
    291275                        case OSystem::EVENT_MOUSEMOVE:
    292276                                activeDialog->handleMouseMoved(mouse.x, mouse.y, 0);
     
    327311                        }
    328312                }
    329313
    330                 // check if event should be sent again (keydown)
    331                 if (_currentKeyDown.keycode != 0 && activeDialog == getTopDialog()) {
    332                         if (_keyRepeatTime < time) {
    333                                 // fire event
    334                                 activeDialog->handleKeyDown(_currentKeyDown.ascii, _currentKeyDown.keycode, _currentKeyDown.flags);
    335                                 _keyRepeatTime = time + kKeyRepeatSustainDelay;
    336                         }
    337                 }
    338 
    339314                // Delay for a moment
    340315                _system->delayMillis(10);
    341316        }
     
    353328
    354329void NewGui::saveState() {
    355330        // Backup old cursor
    356         _currentKeyDown.keycode = 0;
    357331        _lastClick.x = _lastClick.y = 0;
    358332        _lastClick.time = 0;
    359333        _lastClick.count = 0;
  • gui/newgui.h

     
    9999
    100100        bool            _useStdCursor;
    101101
    102         // for continuous events (keyDown)
    103         struct {
    104                 uint16 ascii;
    105                 byte flags;
    106                 int keycode;
    107         } _currentKeyDown;
    108         uint32          _keyRepeatTime;
    109 
    110102        // position and time of last mouse click (used to detect double clicks)
    111103        struct {
    112104                int16 x, y;     // Position of mouse when the click occured
  • common/system.h

     
    747747        struct Event {
    748748                /** The type of the event. */
    749749                EventType type;
     750                /** Flag to indicate if the event is real or synthetic. E.g. keyboard
     751                  * repeat events are synthetic.
     752                  */
     753                bool synthetic;
    750754                /**
    751755                  * Keyboard data; only valid for keyboard events (EVENT_KEYDOWN and
    752756                  * EVENT_KEYUP). For all other event types, content is undefined.
  • engines/sword1/control.h

     
    139139        uint8 *_font, *_redFont;
    140140        uint8 *_screenBuf;
    141141        uint8 _keyPressed;
    142         uint8 _keyRepeat;
    143         uint32 _keyRepeatTime;
    144142        void delay(uint32 msecs);
    145143        uint16 _mouseX, _mouseY, _mouseState;
    146144        bool _mouseDown;
  • engines/sword1/control.cpp

     
    4242
    4343namespace Sword1 {
    4444
    45 enum {
    46         kKeyRepeatInitialDelay = 400,
    47         kKeyRepeatSustainDelay = 100
    48 };
    49 
    5045enum LangStrings {
    5146        STR_PAUSED = 0,
    5247        STR_INSERT_CD_A,
     
    171166        _music = pMusic;
    172167        _sound = pSound;
    173168        _lStrings = _languageStrings + SwordEngine::_systemVars.language * 20;
    174         _keyRepeat = 0;
    175         _keyRepeatTime = 0;
    176169        _selectedButton = 255;
    177170}
    178171
     
    10531046                                        _keyPressed = 8;
    10541047                                else
    10551048                                        _keyPressed = (byte)event.kbd.ascii;
    1056                                 _keyRepeatTime = now + kKeyRepeatInitialDelay;
    1057                                 _keyRepeat = _keyPressed;
    10581049                                // we skip the rest of the delay and return immediately
    10591050                                // to handle keyboard input
    10601051                                return;
    1061                         case OSystem::EVENT_KEYUP:
    1062                                 _keyRepeatTime = 0;
    1063                                 _keyRepeat = 0;
    1064                                 break;
    10651052                        case OSystem::EVENT_MOUSEMOVE:
    10661053                                _mouseX = event.mouse.x;
    10671054                                _mouseY = event.mouse.y;
     
    10931080                                break;
    10941081                        }
    10951082                }
    1096                 if (_keyRepeatTime && now > _keyRepeatTime) {
    1097                         _keyRepeatTime += kKeyRepeatSustainDelay;
    1098                         _keyPressed = _keyRepeat;
    1099                 }
    11001083
    11011084                _system->updateScreen();
    11021085                _system->delayMillis(10);
  • engines/sword2/sword2.cpp

     
    187187        _debugger = NULL;
    188188
    189189        _keyboardEvent.pending = false;
    190         _keyboardEvent.repeat = 0;
    191190        _mouseEvent.pending = false;
    192191
    193192        _wantSfxDebug = false;
     
    377376
    378377                if (ke) {
    379378                        if ((ke->modifiers == OSystem::KBD_CTRL && ke->keycode == 'd') || ke->ascii == '#' || ke->ascii == '~') {
    380                                 // HACK: We have to clear the 'repeat' flag, or
    381                                 // it will probably trigger a keyboard repeat
    382                                 // immediately after the debug console closes.
    383                                 _keyboardEvent.repeat = 0;
    384379                                _debugger->attach();
    385380                        } else if (ke->modifiers == 0 || ke->modifiers == OSystem::KBD_SHIFT) {
    386381                                switch (ke->keycode) {
     
    555550                        }
    556551                        if (!(_inputEventFilter & RD_KEYDOWN)) {
    557552                                _keyboardEvent.pending = true;
    558                                 _keyboardEvent.repeat = now + 400;
    559553                                _keyboardEvent.ascii = event.kbd.ascii;
    560554                                _keyboardEvent.keycode = event.kbd.keycode;
    561555                                _keyboardEvent.modifiers = event.kbd.flags;
    562556                        }
    563557                        break;
    564                 case OSystem::EVENT_KEYUP:
    565                         _keyboardEvent.repeat = 0;
    566                         break;
    567558                case OSystem::EVENT_MOUSEMOVE:
    568559                        if (!(_inputEventFilter & RD_KEYDOWN)) {
    569560                                _mouse->setPos(event.mouse.x, event.mouse.y - MENUDEEP);
     
    612603                        break;
    613604                }
    614605        }
    615 
    616         // Handle keyboard auto-repeat
    617         if (!_keyboardEvent.pending && _keyboardEvent.repeat && now >= _keyboardEvent.repeat) {
    618                 _keyboardEvent.pending = true;
    619                 _keyboardEvent.repeat = now + 100;
    620         }
    621606}
    622607
    623608void Sword2Engine::gameCycle() {
  • engines/sword2/sword2.h

     
    7474
    7575struct KeyboardEvent {
    7676        bool pending;
    77         uint32 repeat;
    7877        uint16 ascii;
    7978        int keycode;
    8079        int modifiers;
  • engines/agos/agos.h

     
    200200        const GameSpecificSettings *gss;
    201201
    202202        byte _keyPressed;
    203         byte _keyRepeatKey;
    204         uint32 _keyRepeatTime;
    205203
    206204        typedef enum {
    207205                FORMAT_NONE,
  • engines/agos/event.cpp

     
    375375                                        _keyPressed = 8;
    376376                                else
    377377                                        _keyPressed = (byte)event.kbd.ascii;
    378 
    379                                 _keyRepeatTime = _system->getMillis() + 400;
    380                                 _keyRepeatKey = _keyPressed;
    381378                                break;
    382                         case OSystem::EVENT_KEYUP:
    383                                 _keyRepeatKey = 0;
    384                                 _keyRepeatTime = 0;
    385                                 break;
    386379                        case OSystem::EVENT_MOUSEMOVE:
    387380                                _sdlMouseX = event.mouse.x;
    388381                                _sdlMouseY = event.mouse.y;
     
    435428
    436429                cur = _system->getMillis();
    437430        } while (cur < start + amount);
    438 
    439         if (_keyPressed == 0 && _keyRepeatKey != 0 && _keyRepeatTime != 0 && cur >= _keyRepeatTime) {
    440                 _keyPressed = _keyRepeatKey;
    441                 _keyRepeatTime = cur + 100;
    442         }
    443431}
    444432
    445433void AGOSEngine::timer_callback() {
  • engines/agos/agos.cpp

     
    8181        _debugger = 0;
    8282
    8383        _keyPressed = 0;
    84         _keyRepeatKey = 0;
    85         _keyRepeatTime = 0;
    8684
    8785        _gameFile = 0;
    8886
  • engines/agi/agi.cpp

     
    113113                        switch (key = event.kbd.keycode) {
    114114                        case 256 + 20:  // left arrow
    115115                        case 260:       // key pad 4
    116                                 key = KEY_LEFT;
     116                                if (!event.synthetic)
     117                                        key = KEY_LEFT;
    117118                                break;
    118119                        case 256 + 19:  // right arrow
    119120                        case 262:       // key pad 6
    120                                 key = KEY_RIGHT;
     121                                if (!event.synthetic)
     122                                        key = KEY_RIGHT;
    121123                                break;
    122124                        case 256 + 17:  // up arrow
    123125                        case 264:       // key pad 8
    124                                 key = KEY_UP;
     126                                if (!event.synthetic)
     127                                        key = KEY_UP;
    125128                                break;
    126129                        case 256 + 18:  // down arrow
    127130                        case 258:       // key pad 2
    128                                 key = KEY_DOWN;
     131                                if (!event.synthetic)
     132                                        key = KEY_DOWN;
    129133                                break;
    130134                        case 256 + 24:  // page up
    131135                        case 265:       // key pad 9
    132                                 key = KEY_UP_RIGHT;
     136                                if (!event.synthetic)
     137                                        key = KEY_UP_RIGHT;
    133138                                break;
    134139                        case 256 + 25:  // page down
    135140                        case 259:       // key pad 3
    136                                 key = KEY_DOWN_RIGHT;
     141                                if (!event.synthetic)
     142                                        key = KEY_DOWN_RIGHT;
    137143                                break;
    138144                        case 256 + 22:  // home
    139145                        case 263:       // key pad 7
    140                                 key = KEY_UP_LEFT;
     146                                if (!event.synthetic)
     147                                        key = KEY_UP_LEFT;
    141148                                break;
    142149                        case 256 + 23:  // end
    143150                        case 257:       // key pad 1
    144                                 key = KEY_DOWN_LEFT;
     151                                if (!event.synthetic)
     152                                        key = KEY_DOWN_LEFT;
    145153                                break;
    146154                        case 261:       // key pad 5
    147155                                key = KEY_STATIONARY;
  • engines/kyra/gui.cpp

     
    597597                calcCoords(_menu[i]);
    598598
    599599        _menuRestoreScreen = true;
    600         _keyboardEvent.pending = 0;
    601         _keyboardEvent.repeat = 0;
     600        _keyPressed = 0;
    602601        _mousePressFlag = false;
    603602       
    604603        _toplevelMenu = 0;
     
    835834                        _mouseWheel = 1;
    836835                        break;
    837836                case OSystem::EVENT_KEYDOWN:
    838                         _keyboardEvent.pending = true;
    839                         _keyboardEvent.repeat = now + 400;
    840                         _keyboardEvent.ascii = event.kbd.ascii;
     837                        _keyPressed = event.kbd.ascii;
    841838                        break;
    842                 case OSystem::EVENT_KEYUP:
    843                         _keyboardEvent.repeat = 0;
    844                         break;
    845839                default:
    846840                        break;
    847841                }
     
    852846                lastScreenUpdate = now;
    853847        }
    854848
    855         if (!_keyboardEvent.pending && _keyboardEvent.repeat && now >= _keyboardEvent.repeat) {
    856                 _keyboardEvent.pending = true;
    857                 _keyboardEvent.repeat = now + 100;
    858         }
    859849        _system->delayMillis(3);
    860850}
    861851
     
    10201010void KyraEngine::gui_updateSavegameString() {
    10211011        int length;
    10221012
    1023         if (_keyboardEvent.pending && _keyboardEvent.ascii) {
     1013        if (_keyPressed) {
    10241014                length = strlen(_savegameName);
    10251015
    1026                 if (_keyboardEvent.ascii > 31 && _keyboardEvent.ascii < 127) {
     1016                if (_keyPressed > 31 && _keyPressed < 127) {
    10271017                        if (length < 31) {
    1028                                 _savegameName[length] = _keyboardEvent.ascii;
     1018                                _savegameName[length] = _keyPressed;
    10291019                                _savegameName[length+1] = 0;
    10301020                                gui_redrawTextfield();
    10311021                        }
    1032                 } else if (_keyboardEvent.ascii == 8 ||_keyboardEvent.ascii == 127) {
     1022                } else if (_keyPressed == 8 ||_keyPressed == 127) {
    10331023                        if (length > 0) {
    10341024                                _savegameName[length-1] = 0;
    10351025                                gui_redrawTextfield();
    10361026                        }
    1037                 } else if (_keyboardEvent.ascii == 13) {
     1027                } else if (_keyPressed == 13) {
    10381028                        _displaySubMenu = false;
    10391029                }
    10401030        }
    10411031
    1042         _keyboardEvent.pending = false;
     1032        _keyPressed = 0;
    10431033}
    10441034
    10451035int KyraEngine::gui_saveGame(Button *button) {
  • engines/kyra/kyra.h

     
    227227        MenuItem item[6];
    228228};
    229229
    230 struct KeyboardEvent {
    231         bool pending;
    232         uint32 repeat;
    233         uint8 ascii;
    234 };
    235 
    236230class KyraEngine : public Engine {
    237231        friend class MusicPlayer;
    238232        friend class Debugger;
     
    839833        int _gameToLoad;
    840834        char _savegameName[31];
    841835        const char *_specialSavegameString;
    842         KeyboardEvent _keyboardEvent;
     836        uint8 _keyPressed;
    843837
    844838        struct KyragemState {
    845839                uint16 nextOperation;
  • engines/saga/input.cpp

     
    121121                                break;
    122122                        }
    123123                        break;
    124                 case OSystem::EVENT_KEYUP:
    125                         _interface->processKeyUp(event.kbd.ascii);
    126                         break;
    127124                case OSystem::EVENT_LBUTTONUP:
    128125                        _leftMouseButtonPressed = false;
    129126                        break;
  • engines/saga/interface.h

     
    222222        void drawStatusBar();
    223223        void setVerbState(int verb, int state);
    224224
    225         bool processAscii(uint16 ascii, bool synthetic = false);
    226         void processKeyUp(uint16 ascii);
     225        bool processAscii(uint16 ascii);
    227226
    228227        void keyBoss();
    229228        void keyBossExit();
     
    243242        }
    244243
    245244private:
    246         static void textInputRepeatCallback(void *refCon);
    247 
    248245        void drawInventory(Surface *backBuffer);
    249246        void updateInventory(int pos);
    250247        void inventoryChangePos(int chg);
     
    343340        void calcOptionSaveSlider();
    344341        bool processTextInput(uint16 ascii);
    345342        void processStatusTextInput(uint16 ascii);
    346         void textInputStartRepeat(uint16 ascii);
    347         void textInputRepeat(void);
    348343
    349344public:
    350345        void converseInit(void);
     
    452447
    453448        uint _statusTextInputPos;
    454449
    455         int _textInputRepeatPhase;
    456         uint16 _textInputRepeatChar;
    457 
    458450        PalEntry _mapSavedPal[PAL_ENTRIES];
    459451        bool _mapPanelCrossHairState;
    460452
  • engines/saga/interface.cpp

     
    212212                error("Interface::Interface(): not enough memory");
    213213        }
    214214
    215         _textInputRepeatPhase = 0;
    216215        _textInput = false;
    217216        _statusTextInput = false;
    218217        _statusTextInputState = kStatusTextInputFirstRun;
     
    316315                _textInput = true;
    317316                _textInputStringLength = strlen(_textInputString);
    318317                _textInputPos = _textInputStringLength + 1;
    319                 _textInputRepeatPhase = 0;
    320318                break;
    321319        case kPanelMap:
    322320                mapPanelShow();
     
    337335                _textInputString[0] = 0;
    338336                _textInputStringLength = 0;
    339337                _textInputPos = _textInputStringLength + 1;
    340                 _textInputRepeatPhase = 0;
    341338                break;
    342339        }
    343340
    344341        draw();
    345342}
    346343
    347 bool Interface::processAscii(uint16 ascii, bool synthetic) {
     344bool Interface::processAscii(uint16 ascii) {
    348345        // TODO: Checking for Esc and Enter below is a bit hackish, and
    349346        // and probably only works with the English version. Maybe we should
    350347        // add a flag to the button so it can indicate if it's the default or
     
    352349
    353350        int i;
    354351        PanelButton *panelButton;
    355         if (!synthetic)
    356                 _textInputRepeatPhase = 0;
    357352        if (_statusTextInput) {
    358353                processStatusTextInput(ascii);
    359354                return true;
     
    536531        return false;
    537532}
    538533
    539 #define KEYBOARD_REPEAT_DELAY1 300000L
    540 #define KEYBOARD_REPEAT_DELAY2 50000L
    541 
    542 void Interface::textInputRepeatCallback(void *refCon) {
    543         ((Interface *)refCon)->textInputRepeat();
    544 }
    545 
    546 void Interface::textInputStartRepeat(uint16 ascii) {
    547         if (!_textInputRepeatPhase) {
    548                 _textInputRepeatPhase = 1;
    549                 _vm->_timer->removeTimerProc(&textInputRepeatCallback);
    550                 _vm->_timer->installTimerProc(&textInputRepeatCallback, KEYBOARD_REPEAT_DELAY1, this);
    551         }
    552 
    553         _textInputRepeatChar = ascii;
    554 }
    555 
    556 void Interface::textInputRepeat() {
    557         if (_textInputRepeatPhase == 1) {
    558                 _textInputRepeatPhase = 2;
    559                 _vm->_timer->removeTimerProc(&textInputRepeatCallback);
    560                 _vm->_timer->installTimerProc(&textInputRepeatCallback, KEYBOARD_REPEAT_DELAY2, this);
    561         } else if (_textInputRepeatPhase == 2) {
    562                 processAscii(_textInputRepeatChar, true);
    563         }
    564 }
    565 
    566 void Interface::processKeyUp(uint16 ascii) {
    567         if (_textInputRepeatPhase) {
    568                 _vm->_timer->removeTimerProc(&textInputRepeatCallback);
    569                 _textInputRepeatPhase = 0;
    570         }
    571 }
    572 
    573534void Interface::setStatusText(const char *text, int statusColor) {
    574535        assert(text != NULL);
    575536        assert(strlen(text) < STATUS_TEXT_LEN);
     
    928889
    929890void Interface::processStatusTextInput(uint16 ascii) {
    930891
    931         textInputStartRepeat(ascii);
    932892        switch (ascii) {
    933893        case 27: // esc
    934894                _statusTextInputState = kStatusTextInputAborted;
     
    968928        memset(tempString, 0, SAVE_TITLE_SIZE);
    969929        ch[1] = 0;
    970930
    971         textInputStartRepeat(ascii);
    972 
    973931        switch (ascii) {
    974932        case 13:
    975933                return false;
  • backends/events/default/default-events.cpp

     
    3333        _shouldQuit(false) {
    3434
    3535        assert(_boss);
     36
     37        // Reset key repeat
     38        _currentKeyDown.keycode = 0;
    3639}
    3740
    3841DefaultEventManager::~DefaultEventManager() {
     
    4043}
    4144
    4245bool DefaultEventManager::pollEvent(OSystem::Event &event) {
     46        uint32 time = _boss->getMillis();
    4347        bool result;
    4448       
    4549        result = _boss->pollEvent(event);
    4650       
    4751        if (result) {
     52                event.synthetic = false;
    4853                switch (event.type) {
    4954                case OSystem::EVENT_KEYDOWN:
     55                        _modifierState = event.kbd.flags;
     56
     57                        // init continuous event stream
     58                        // not done on PalmOS because keyboard is emulated and keyup is not generated
     59#if !defined(PALMOS_MODE)
     60                        _currentKeyDown.ascii = event.kbd.ascii;
     61                        _currentKeyDown.keycode = event.kbd.keycode;
     62                        _currentKeyDown.flags = event.kbd.flags;
     63                        _keyRepeatTime = time + kKeyRepeatInitialDelay;
     64#endif
     65                        break;
    5066                case OSystem::EVENT_KEYUP:
    5167                        _modifierState = event.kbd.flags;
     68                        if (event.kbd.keycode == _currentKeyDown.keycode) {
     69                                // Only stop firing events if it's the current key
     70                                _currentKeyDown.keycode = 0;
     71                        }
    5272                        break;
     73
    5374                case OSystem::EVENT_MOUSEMOVE:
    5475                        _mousePos = event.mouse;
    5576                        break;
     
    79100                default:
    80101                        break;
    81102                }
     103        } else {
     104                // Check if event should be sent again (keydown)
     105                if (_currentKeyDown.keycode != 0 && _keyRepeatTime < time) {
     106                        // fire event
     107                        event.type = OSystem::EVENT_KEYDOWN;
     108                        event.synthetic = true;
     109                        event.kbd.ascii = _currentKeyDown.ascii;
     110                        event.kbd.keycode = _currentKeyDown.keycode;
     111                        event.kbd.flags = _currentKeyDown.flags;
     112                        _keyRepeatTime = time + kKeyRepeatSustainDelay;
     113                        result = true;
     114                }
    82115        }
    83116       
    84117        return result;
  • backends/events/default/default-events.h

     
    4646        int _modifierState;
    4747        bool _shouldQuit;
    4848
     49        // for continuous events (keyDown)
     50        enum {
     51                kKeyRepeatInitialDelay = 400,
     52                kKeyRepeatSustainDelay = 100
     53        };
     54
     55        struct {
     56                uint16 ascii;
     57                byte flags;
     58                int keycode;
     59        } _currentKeyDown;
     60        uint32 _keyRepeatTime;
     61
    4962public:
    5063        DefaultEventManager(OSystem *boss);
    5164        ~DefaultEventManager();