ResidualVM logo ResidualVM website - Forums - Contact us BuildBot - Doxygen - Wiki curved edge

default-events.cpp

Go to the documentation of this file.
00001 /* ScummVM - Graphic Adventure Engine
00002  *
00003  * ScummVM is the legal property of its developers, whose names
00004  * are too numerous to list here. Please refer to the COPYRIGHT
00005  * file distributed with this source distribution.
00006  *
00007  * This program is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU General Public License
00009  * as published by the Free Software Foundation; either version 2
00010  * of the License, or (at your option) any later version.
00011  *
00012  * This program is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU General Public License
00018  * along with this program; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00020  *
00021  */
00022 
00023 #include "common/scummsys.h"
00024 
00025 #if !defined(DISABLE_DEFAULT_EVENTMANAGER)
00026 
00027 #include "common/system.h"
00028 #include "common/config-manager.h"
00029 #include "common/translation.h"
00030 #include "backends/events/default/default-events.h"
00031 #include "backends/keymapper/keymapper.h"
00032 #include "backends/keymapper/remap-dialog.h"
00033 #include "backends/vkeybd/virtual-keyboard.h"
00034 
00035 #include "engines/engine.h"
00036 #include "gui/message.h"
00037 
00038 DefaultEventManager::DefaultEventManager(Common::EventSource *boss) :
00039     _buttonState(0),
00040     _modifierState(0),
00041     _shouldQuit(false),
00042     _shouldRTL(false),
00043     _confirmExitDialogActive(false),
00044     _shouldGenerateKeyRepeatEvents(true) {
00045 
00046     assert(boss);
00047 
00048     _dispatcher.registerSource(boss, false);
00049     _dispatcher.registerSource(&_artificialEventSource, false);
00050 
00051     _dispatcher.registerObserver(this, kEventManPriority, false);
00052 
00053     // Reset key repeat
00054     _keyRepeatTime = 0;
00055 
00056 #ifdef ENABLE_VKEYBD
00057     _vk = nullptr;
00058 #endif
00059 #ifdef ENABLE_KEYMAPPER
00060     _keymapper = new Common::Keymapper(this);
00061     // EventDispatcher will automatically free the keymapper
00062     _dispatcher.registerMapper(_keymapper);
00063     _remap = false;
00064 #else
00065     _dispatcher.registerMapper(new Common::DefaultEventMapper());
00066 #endif
00067 }
00068 
00069 DefaultEventManager::~DefaultEventManager() {
00070 #ifdef ENABLE_VKEYBD
00071     delete _vk;
00072 #endif
00073 }
00074 
00075 void DefaultEventManager::init() {
00076 #ifdef ENABLE_VKEYBD
00077     _vk = new Common::VirtualKeyboard();
00078 
00079     if (ConfMan.hasKey("vkeybd_pack_name")) {
00080         _vk->loadKeyboardPack(ConfMan.get("vkeybd_pack_name"));
00081     } else {
00082         _vk->loadKeyboardPack("vkeybd_default");
00083     }
00084 #endif
00085 }
00086 
00087 bool DefaultEventManager::pollEvent(Common::Event &event) {
00088     _dispatcher.dispatch();
00089 
00090     if (_shouldGenerateKeyRepeatEvents) {
00091         handleKeyRepeat();
00092     }
00093 
00094     if (_eventQueue.empty()) {
00095         return false;
00096     }
00097 
00098     event = _eventQueue.pop();
00099     bool forwardEvent = true;
00100 
00101     switch (event.type) {
00102     case Common::EVENT_KEYDOWN:
00103         _modifierState = event.kbd.flags;
00104 
00105         if (event.kbd.keycode == Common::KEYCODE_BACKSPACE) {
00106             // WORKAROUND: Some engines incorrectly attempt to use the
00107             // ascii value instead of the keycode to detect the backspace
00108             // key (a non-portable behavior). This fails at least on
00109             // Mac OS X, possibly also on other systems.
00110             // As a workaround, we force the ascii value for backspace
00111             // key pressed. A better fix would be for engines to stop
00112             // making invalid assumptions about ascii values.
00113             event.kbd.ascii = Common::KEYCODE_BACKSPACE;
00114             _currentKeyDown.ascii = Common::KEYCODE_BACKSPACE;
00115         }
00116         break;
00117 
00118     case Common::EVENT_KEYUP:
00119         _modifierState = event.kbd.flags;
00120         break;
00121 
00122     case Common::EVENT_MOUSEMOVE:
00123         _mousePos = event.mouse;
00124         break;
00125 
00126     case Common::EVENT_LBUTTONDOWN:
00127         _mousePos = event.mouse;
00128         _buttonState |= LBUTTON;
00129         break;
00130 
00131     case Common::EVENT_LBUTTONUP:
00132         _mousePos = event.mouse;
00133         _buttonState &= ~LBUTTON;
00134         break;
00135 
00136     case Common::EVENT_RBUTTONDOWN:
00137         _mousePos = event.mouse;
00138         _buttonState |= RBUTTON;
00139         break;
00140 
00141     case Common::EVENT_RBUTTONUP:
00142         _mousePos = event.mouse;
00143         _buttonState &= ~RBUTTON;
00144         break;
00145 
00146     case Common::EVENT_MAINMENU:
00147         if (g_engine && !g_engine->isPaused())
00148             g_engine->openMainMenuDialog();
00149 
00150         if (_shouldQuit)
00151             event.type = Common::EVENT_QUIT;
00152         else if (_shouldRTL)
00153             event.type = Common::EVENT_RTL;
00154         break;
00155 #ifdef ENABLE_VKEYBD
00156     case Common::EVENT_VIRTUAL_KEYBOARD:
00157         if (!_vk)
00158             break;
00159 
00160         if (_vk->isDisplaying()) {
00161             _vk->close(true);
00162         } else {
00163             if (g_engine)
00164                 g_engine->pauseEngine(true);
00165             _vk->show();
00166             if (g_engine)
00167                 g_engine->pauseEngine(false);
00168             forwardEvent = false;
00169         }
00170         break;
00171 #endif
00172 #ifdef ENABLE_KEYMAPPER
00173     case Common::EVENT_KEYMAPPER_REMAP:
00174         if (!_remap) {
00175             _remap = true;
00176             Common::RemapDialog _remapDialog;
00177             if (g_engine)
00178                 g_engine->pauseEngine(true);
00179             _remapDialog.runModal();
00180             if (g_engine)
00181                 g_engine->pauseEngine(false);
00182             _remap = false;
00183         }
00184         break;
00185 #endif
00186     case Common::EVENT_RTL:
00187         if (ConfMan.getBool("confirm_exit")) {
00188             if (g_engine)
00189                 g_engine->pauseEngine(true);
00190             GUI::MessageDialog alert(_("Do you really want to return to the Launcher?"), _("Launcher"), _("Cancel"));
00191             forwardEvent = _shouldRTL = (alert.runModal() == GUI::kMessageOK);
00192             if (g_engine)
00193                 g_engine->pauseEngine(false);
00194         } else
00195             _shouldRTL = true;
00196         break;
00197 
00198     case Common::EVENT_MUTE:
00199         if (g_engine)
00200             g_engine->flipMute();
00201         break;
00202 
00203     case Common::EVENT_QUIT:
00204         if (ConfMan.getBool("confirm_exit")) {
00205             if (_confirmExitDialogActive) {
00206                 forwardEvent = false;
00207                 break;
00208             }
00209             _confirmExitDialogActive = true;
00210             if (g_engine)
00211                 g_engine->pauseEngine(true);
00212             GUI::MessageDialog alert(_("Do you really want to quit?"), _("Quit"), _("Cancel"));
00213             forwardEvent = _shouldQuit = (alert.runModal() == GUI::kMessageOK);
00214             if (g_engine)
00215                 g_engine->pauseEngine(false);
00216             _confirmExitDialogActive = false;
00217         } else
00218             _shouldQuit = true;
00219 
00220         break;
00221 
00222     default:
00223         break;
00224     }
00225 
00226     return forwardEvent;
00227 }
00228 
00229 void DefaultEventManager::handleKeyRepeat() {
00230     uint32 time = g_system->getMillis(true);
00231 
00232     if (!_eventQueue.empty()) {
00233         // Peek in the event queue
00234         const Common::Event &nextEvent = _eventQueue.front();
00235 
00236         switch (nextEvent.type) {
00237         case Common::EVENT_KEYDOWN:
00238             // init continuous event stream
00239             _currentKeyDown = nextEvent.kbd;
00240             _keyRepeatTime = time + kKeyRepeatInitialDelay;
00241             break;
00242 
00243         case Common::EVENT_KEYUP:
00244             if (nextEvent.kbd.keycode == _currentKeyDown.keycode) {
00245                 // Only stop firing events if it's the current key
00246                 _currentKeyDown.keycode = Common::KEYCODE_INVALID;
00247             }
00248             break;
00249 
00250         default:
00251             break;
00252         }
00253     } else {
00254         // Check if event should be sent again (keydown)
00255         if (_currentKeyDown.keycode != Common::KEYCODE_INVALID && _keyRepeatTime <= time) {
00256             // fire event
00257             Common::Event repeatEvent;
00258             repeatEvent.type = Common::EVENT_KEYDOWN;
00259             repeatEvent.kbdRepeat = true;
00260             repeatEvent.kbd = _currentKeyDown;
00261             _keyRepeatTime = time + kKeyRepeatSustainDelay;
00262 
00263             _eventQueue.push(repeatEvent);
00264         }
00265     }
00266 }
00267 
00268 void DefaultEventManager::pushEvent(const Common::Event &event) {
00269     // If already received an EVENT_QUIT, don't add another one
00270     if (event.type == Common::EVENT_QUIT) {
00271         if (!_shouldQuit)
00272             _artificialEventSource.addEvent(event);
00273     } else
00274         _artificialEventSource.addEvent(event);
00275 }
00276 
00277 void DefaultEventManager::purgeMouseEvents() {
00278     _dispatcher.dispatch();
00279 
00280     Common::Queue<Common::Event> filteredQueue;
00281     while (!_eventQueue.empty()) {
00282         Common::Event event = _eventQueue.pop();
00283         switch (event.type) {
00284         case Common::EVENT_MOUSEMOVE:
00285         case Common::EVENT_LBUTTONDOWN:
00286         case Common::EVENT_LBUTTONUP:
00287         case Common::EVENT_RBUTTONDOWN:
00288         case Common::EVENT_RBUTTONUP:
00289         case Common::EVENT_WHEELUP:
00290         case Common::EVENT_WHEELDOWN:
00291         case Common::EVENT_MBUTTONDOWN:
00292         case Common::EVENT_MBUTTONUP:
00293             // do nothing
00294             break;
00295         default:
00296             filteredQueue.push(event);
00297             break;
00298         }
00299     }
00300     _eventQueue = filteredQueue;
00301 }
00302 
00303 #endif // !defined(DISABLE_DEFAULT_EVENTMANAGER)


Generated on Sat Apr 20 2019 05:02:23 for ResidualVM by doxygen 1.7.1
curved edge   curved edge