Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/trunk/src/libraries/core/input/InputManager.cc @ 8382

Last change on this file since 8382 was 8351, checked in by rgrieder, 14 years ago

Merged kicklib2 branch back to trunk (includes former branches ois_update, mac_osx and kicklib).

Notes for updating

Linux:
You don't need an extra package for CEGUILua and Tolua, it's already shipped with CEGUI.
However you do need to make sure that the OgreRenderer is installed too with CEGUI 0.7 (may be a separate package).
Also, Orxonox now recognises if you install the CgProgramManager (a separate package available on newer Ubuntu on Debian systems).

Windows:
Download the new dependency packages versioned 6.0 and use these. If you have problems with that or if you don't like the in game console problem mentioned below, you can download the new 4.3 version of the packages (only available for Visual Studio 2005/2008).

Key new features:

  • *Support for Mac OS X*
  • Visual Studio 2010 support
  • Bullet library update to 2.77
  • OIS library update to 1.3
  • Support for CEGUI 0.7 —> Support for Arch Linux and even SuSE
  • Improved install target
  • Compiles now with GCC 4.6
  • Ogre Cg Shader plugin activated for Linux if available
  • And of course lots of bug fixes

There are also some regressions:

  • No support for CEGUI 0.5, Ogre 1.4 and boost 1.35 - 1.39 any more
  • In game console is not working in main menu for CEGUI 0.7
  • Tolua (just the C lib, not the application) and CEGUILua libraries are no longer in our repository. —> You will need to get these as well when compiling Orxonox
  • And of course lots of new bugs we don't yet know about
  • Property svn:eol-style set to native
File size: 24.3 KB
Line 
1/*
2 *   ORXONOX - the hottest 3D action shooter ever to exist
3 *                    > www.orxonox.net <
4 *
5 *
6 *   License notice:
7 *
8 *   This program is free software; you can redistribute it and/or
9 *   modify it under the terms of the GNU General Public License
10 *   as published by the Free Software Foundation; either version 2
11 *   of the License, or (at your option) any later version.
12 *
13 *   This program is distributed in the hope that it will be useful,
14 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
15 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 *   GNU General Public License for more details.
17 *
18 *   You should have received a copy of the GNU General Public License
19 *   along with this program; if not, write to the Free Software
20 *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
21 *
22 *   Author:
23 *      Reto Grieder
24 *   Co-authors:
25 *      ...
26 *
27 */
28
29/**
30@file
31@brief
32    Implementation of the InputManager and a static variable from the InputHandler.
33*/
34
35#include "InputManager.h"
36
37#include <cassert>
38#include <climits>
39#include <ois/OISException.h>
40#include <ois/OISInputManager.h>
41#include <boost/foreach.hpp>
42#include <loki/ScopeGuard.h>
43
44#include "util/Clock.h"
45#include "util/Convert.h"
46#include "util/Exception.h"
47#include "core/CoreIncludes.h"
48#include "core/ConfigValueIncludes.h"
49#include "core/CommandLineParser.h"
50#include "core/GraphicsManager.h"
51#include "core/command/ConsoleCommand.h"
52#include "core/command/Functor.h"
53
54#include "InputBuffer.h"
55#include "JoyStick.h"
56#include "JoyStickQuantityListener.h"
57#include "Mouse.h"
58#include "Keyboard.h"
59
60namespace orxonox
61{
62    SetCommandLineSwitch(keyboard_no_grab).information("Whether not to exclusively grab the keyboard");
63
64    static const std::string __CC_InputManager_name = "InputManager";
65    static const std::string __CC_calibrate_name = "calibrate";
66    static const std::string __CC_reload_name = "reload";
67
68    SetConsoleCommand(__CC_InputManager_name, __CC_calibrate_name, &InputManager::calibrate).addShortcut();
69    SetConsoleCommand(__CC_InputManager_name, __CC_reload_name,    &InputManager::reload   );
70
71    // Abuse of this source file for the InputHandler
72    InputHandler InputHandler::EMPTY;
73
74    InputManager* InputManager::singletonPtr_s = 0;
75
76    //! Defines the |= operator for easier use.
77    inline InputManager::State operator|=(InputManager::State& lval, InputManager::State rval)
78    {
79        return (lval = (InputManager::State)(lval | rval));
80    }
81
82    //! Defines the &= operator for easier use.
83    inline InputManager::State operator&=(InputManager::State& lval, int rval)
84    {
85        return (lval = (InputManager::State)(lval & rval));
86    }
87
88    // ############################################################
89    // #####                  Initialisation                  #####
90    // ##########                                        ##########
91    // ############################################################
92    InputManager::InputManager()
93        : internalState_(Bad)
94        , oisInputManager_(0)
95        , devices_(2)
96        , exclusiveMouse_(TriBool::False)
97        , emptyState_(0)
98        , calibratorCallbackHandler_(0)
99    {
100        RegisterRootObject(InputManager);
101
102        CCOUT(4) << "Constructing..." << std::endl;
103
104        // Allocate space for the function call buffer
105        this->callBuffer_.reserve(16);
106
107        this->setConfigValues();
108
109        if (GraphicsManager::getInstance().isFullScreen())
110            exclusiveMouse_ = TriBool::True;
111        this->loadDevices();
112
113        // Lowest priority empty InputState
114        emptyState_ = createInputState("empty", false, false, InputStatePriority::Empty);
115        emptyState_->setHandler(&InputHandler::EMPTY);
116        activeStates_[emptyState_->getPriority()] = emptyState_;
117
118        // Joy stick calibration helper callback
119        InputState* calibrator = createInputState("calibrator", false, false, InputStatePriority::Calibrator);
120        calibrator->setHandler(&InputHandler::EMPTY);
121        calibratorCallbackHandler_ = new InputBuffer();
122        calibratorCallbackHandler_->registerListener(this, &InputManager::stopCalibration, '\r', true);
123        calibrator->setKeyHandler(calibratorCallbackHandler_);
124
125        this->updateActiveStates();
126
127        ModifyConsoleCommand(__CC_InputManager_name, __CC_calibrate_name).setObject(this);
128        ModifyConsoleCommand(__CC_InputManager_name, __CC_reload_name).setObject(this);
129
130        CCOUT(4) << "Construction complete." << std::endl;
131        internalState_ = Nothing;
132    }
133
134    void InputManager::setConfigValues()
135    {
136    }
137
138    /**
139    @brief
140        Creates the OIS::InputMananger, the keyboard, the mouse and
141        the joys ticks. If either of the first two fail, this method throws an exception.
142    */
143    void InputManager::loadDevices()
144    {
145        CCOUT(4) << "Loading input devices..." << std::endl;
146
147        // When loading the devices they should not already be loaded
148        assert(internalState_ & Bad);
149        assert(devices_[InputDeviceEnumerator::Mouse] == 0);
150        assert(devices_[InputDeviceEnumerator::Keyboard] == 0);
151        assert(devices_.size() == InputDeviceEnumerator::FirstJoyStick);
152
153        typedef std::pair<std::string, std::string> StringPair;
154
155        // Fill parameter list
156        OIS::ParamList paramList;
157        size_t windowHnd = GraphicsManager::getInstance().getRenderWindowHandle();
158        paramList.insert(StringPair("WINDOW", multi_cast<std::string>(windowHnd)));
159#if defined(ORXONOX_PLATFORM_WINDOWS)
160        paramList.insert(StringPair("w32_keyboard", "DISCL_NONEXCLUSIVE"));
161        paramList.insert(StringPair("w32_keyboard", "DISCL_FOREGROUND"));
162        paramList.insert(StringPair("w32_mouse", "DISCL_FOREGROUND"));
163        if (exclusiveMouse_ == TriBool::True || GraphicsManager::getInstance().isFullScreen())
164        {
165            // Disable Windows key plus special keys (like play, stop, next, etc.)
166            paramList.insert(StringPair("w32_keyboard", "DISCL_NOWINKEY"));
167            paramList.insert(StringPair("w32_mouse", "DISCL_EXCLUSIVE"));
168        }
169        else
170            paramList.insert(StringPair("w32_mouse", "DISCL_NONEXCLUSIVE"));
171#elif defined(ORXONOX_PLATFORM_LINUX)
172        // Enabling this is probably a bad idea, but whenever orxonox crashes, the setting stays on
173        // Trouble might be that the Pressed event occurs a bit too often...
174        paramList.insert(StringPair("XAutoRepeatOn", "true"));
175
176        if (exclusiveMouse_ == TriBool::True || GraphicsManager::getInstance().isFullScreen())
177        {
178            if (CommandLineParser::getValue("keyboard_no_grab").getBool())
179                paramList.insert(StringPair("x11_keyboard_grab", "false"));
180            else
181                paramList.insert(StringPair("x11_keyboard_grab", "true"));
182            paramList.insert(StringPair("x11_mouse_grab",  "true"));
183            paramList.insert(StringPair("x11_mouse_hide", "true"));
184        }
185        else
186        {
187            paramList.insert(StringPair("x11_keyboard_grab", "false"));
188            paramList.insert(StringPair("x11_mouse_grab",  "false"));
189            paramList.insert(StringPair("x11_mouse_hide", "false"));
190        }
191#endif
192
193        try
194        {
195            oisInputManager_ = OIS::InputManager::createInputSystem(paramList);
196            // Exception-safety
197            Loki::ScopeGuard guard = Loki::MakeGuard(OIS::InputManager::destroyInputSystem, oisInputManager_);
198            CCOUT(4) << "Created OIS input manager." << std::endl;
199
200            if (oisInputManager_->getNumberOfDevices(OIS::OISKeyboard) > 0)
201                devices_[InputDeviceEnumerator::Keyboard] = new Keyboard(InputDeviceEnumerator::Keyboard, oisInputManager_);
202            else
203                ThrowException(InitialisationFailed, "InputManager: No keyboard found, cannot proceed!");
204
205            // Successful initialisation
206            guard.Dismiss();
207        }
208        catch (const std::exception& ex)
209        {
210            oisInputManager_ = NULL;
211            internalState_ |= Bad;
212            ThrowException(InitialisationFailed, "Could not initialise the input system: " << ex.what());
213        }
214
215        this->loadMouse();
216        this->loadJoySticks();
217
218        // Reorder states in case some joy sticks were added/removed
219        this->updateActiveStates();
220
221        CCOUT(4) << "Input devices loaded." << std::endl;
222    }
223
224    //! Creates a new orxonox::Mouse
225    void InputManager::loadMouse()
226    {
227        if (oisInputManager_->getNumberOfDevices(OIS::OISMouse) > 0)
228        {
229            try
230            {
231                devices_[InputDeviceEnumerator::Mouse] = new Mouse(InputDeviceEnumerator::Mouse, oisInputManager_);
232            }
233            catch (const std::exception& ex)
234            {
235                CCOUT(2) << "Warning: Failed to create Mouse:" << ex.what() << std::endl
236                         << "Proceeding without mouse support." << std::endl;
237            }
238        }
239        else
240            CCOUT(2) << "Warning: No mouse found! Proceeding without mouse support." << std::endl;
241    }
242
243    //! Creates as many joy sticks as are available.
244    void InputManager::loadJoySticks()
245    {
246        for (int i = 0; i < oisInputManager_->getNumberOfDevices(OIS::OISJoyStick); i++)
247        {
248            try
249            {
250                devices_.push_back(new JoyStick(InputDeviceEnumerator::FirstJoyStick + i, oisInputManager_));
251            }
252            catch (const std::exception& ex)
253            {
254                CCOUT(2) << "Warning: Failed to create joy stick: " << ex.what() << std::endl;
255            }
256        }
257
258        // inform all JoyStick Device Number Listeners
259        std::vector<JoyStick*> joyStickList;
260        for (unsigned int i = InputDeviceEnumerator::FirstJoyStick; i < devices_.size(); ++i)
261            joyStickList.push_back(static_cast<JoyStick*>(devices_[i]));
262        JoyStickQuantityListener::changeJoyStickQuantity(joyStickList);
263    }
264
265    // ############################################################
266    // #####                    Destruction                   #####
267    // ##########                                        ##########
268    // ############################################################
269
270    InputManager::~InputManager()
271    {
272        CCOUT(3) << "Destroying..." << std::endl;
273
274        // Leave all active InputStates (except "empty")
275        while (this->activeStates_.size() > 1)
276            this->leaveState(this->activeStates_.rbegin()->second->getName());
277        this->activeStates_.clear();
278
279        // Destroy calibrator helper handler and state
280        this->destroyState("calibrator");
281        // Destroy KeyDetector and state
282        calibratorCallbackHandler_->destroy();
283        // Destroy the empty InputState
284        this->destroyStateInternal(this->emptyState_);
285
286        // Destroy all user InputStates
287        while (statesByName_.size() > 0)
288            this->destroyStateInternal(statesByName_.rbegin()->second);
289
290        if (!(internalState_ & Bad))
291            this->destroyDevices();
292
293        // Reset console commands
294        ModifyConsoleCommand(__CC_InputManager_name, __CC_calibrate_name).setObject(0);
295        ModifyConsoleCommand(__CC_InputManager_name, __CC_reload_name).setObject(0);
296
297        CCOUT(3) << "Destruction complete." << std::endl;
298    }
299
300    /**
301    @brief
302        Destoys all input devices (joy sticks, mouse, keyboard and OIS::InputManager)
303    @throw
304        Method does not throw
305    */
306    void InputManager::destroyDevices()
307    {
308        CCOUT(4) << "Destroying devices..." << std::endl;
309
310        BOOST_FOREACH(InputDevice*& device, devices_)
311        {
312            if (device == NULL)
313                continue;
314            const std::string& className = device->getClassName();
315            delete device;
316            device = 0;
317            CCOUT(4) << className << " destroyed." << std::endl;
318        }
319        devices_.resize(InputDeviceEnumerator::FirstJoyStick);
320
321        assert(oisInputManager_ != NULL);
322        try
323        {
324            OIS::InputManager::destroyInputSystem(oisInputManager_);
325        }
326        catch (const OIS::Exception& ex)
327        {
328            COUT(1) << "OIS::InputManager destruction failed" << ex.eText << std::endl
329                    << "    Potential resource leak!" << std::endl;
330        }
331        oisInputManager_ = NULL;
332
333        internalState_ |= Bad;
334        CCOUT(4) << "Destroyed devices." << std::endl;
335    }
336
337    // ############################################################
338    // #####                     Reloading                    #####
339    // ##########                                        ##########
340    // ############################################################
341
342    void InputManager::reload()
343    {
344        if (internalState_ & Calibrating)
345            CCOUT(2) << "Warning: Cannot reload input system. Joy sticks are currently being calibrated." << std::endl;
346        else
347            reloadInternal();
348    }
349
350    //! Internal reload method. Destroys the OIS devices and loads them again.
351    void InputManager::reloadInternal()
352    {
353        CCOUT(4) << "Reloading ..." << std::endl;
354
355        this->destroyDevices();
356        this->loadDevices();
357
358        internalState_ &= ~Bad;
359        CCOUT(4) << "Reloading complete." << std::endl;
360    }
361
362    // ############################################################
363    // #####                  Runtime Methods                 #####
364    // ##########                                        ##########
365    // ############################################################
366
367    void InputManager::preUpdate(const Clock& time)
368    {
369        if (internalState_ & Bad)
370            ThrowException(General, "InputManager was not correctly reloaded.");
371
372        // check whether a state has changed its EMPTY situation
373        bool bUpdateRequired = false;
374        for (std::map<int, InputState*>::iterator it = activeStates_.begin(); it != activeStates_.end(); ++it)
375        {
376            if (it->second->hasExpired())
377            {
378                it->second->resetExpiration();
379                bUpdateRequired = true;
380            }
381        }
382        if (bUpdateRequired)
383            updateActiveStates();
384
385        // Capture all the input and collect the function calls
386        // No event gets triggered here yet!
387        BOOST_FOREACH(InputDevice* device, devices_)
388            if (device != NULL)
389                device->update(time);
390
391        // Collect function calls for the update
392        for (unsigned int i = 0; i < activeStatesTicked_.size(); ++i)
393            activeStatesTicked_[i]->update(time.getDeltaTime());
394
395        // Execute all cached function calls in order
396        // Why so complicated? The problem is that an InputHandler could trigger
397        // a reload that would destroy the OIS devices or it could even leave and
398        // then destroy its own InputState. That would of course lead to access
399        // violations.
400        // If we delay the calls, then OIS and and the InputStates are not anymore
401        // in the call stack and can therefore be edited.
402        for (size_t i = 0; i < this->callBuffer_.size(); ++i)
403            this->callBuffer_[i]();
404
405        this->callBuffer_.clear();
406    }
407
408    /**
409    @brief
410        Updates the currently active states (according to activeStates_) for each device.
411        Also, a list of all active states (no duplicates!) is compiled for the general preUpdate().
412    */
413    void InputManager::updateActiveStates()
414    {
415        // Calculate the stack of input states
416        // and assign it to the corresponding device
417        for (unsigned int i = 0; i < devices_.size(); ++i)
418        {
419            if (devices_[i] == NULL)
420                continue;
421            std::vector<InputState*>& states = devices_[i]->getStateListRef();
422            bool occupied = false;
423            states.clear();
424            for (std::map<int, InputState*>::reverse_iterator rit = activeStates_.rbegin(); rit != activeStates_.rend(); ++rit)
425            {
426                if (rit->second->isInputDeviceEnabled(i) && (!occupied || rit->second->bAlwaysGetsInput_))
427                {
428                    states.push_back(rit->second);
429                    if (!rit->second->bTransparent_)
430                        occupied = true;
431                }
432            }
433        }
434
435        // See that we only update each InputState once for each device
436        // Using an std::set to avoid duplicates
437        std::set<InputState*> tempSet;
438        for (unsigned int i = 0; i < devices_.size(); ++i)
439            if (devices_[i] != NULL)
440                for (unsigned int iState = 0; iState < devices_[i]->getStateListRef().size(); ++iState)
441                    tempSet.insert(devices_[i]->getStateListRef()[iState]);
442
443        // Copy the content of the std::set back to the actual vector
444        activeStatesTicked_.clear();
445        for (std::set<InputState*>::const_iterator it = tempSet.begin();it != tempSet.end(); ++it)
446            activeStatesTicked_.push_back(*it);
447
448        // Check whether we have to change the mouse mode
449        TriBool::Value requestedMode = TriBool::Dontcare;
450        std::vector<InputState*>& mouseStates = devices_[InputDeviceEnumerator::Mouse]->getStateListRef();
451        if (mouseStates.empty())
452            requestedMode = TriBool::False;
453        else
454            requestedMode = mouseStates.front()->getMouseExclusive();
455        if (requestedMode != TriBool::Dontcare && exclusiveMouse_ != requestedMode)
456        {
457            exclusiveMouse_ = requestedMode;
458            if (!GraphicsManager::getInstance().isFullScreen())
459                this->reloadInternal();
460        }
461    }
462
463    void InputManager::clearBuffers()
464    {
465        BOOST_FOREACH(InputDevice* device, devices_)
466            if (device != NULL)
467                device->clearBuffers();
468    }
469
470    void InputManager::calibrate()
471    {
472        COUT(0) << "Move all joy stick axes fully in all directions." << std::endl
473                << "When done, put the axex in the middle position and press enter." << std::endl;
474
475        BOOST_FOREACH(InputDevice* device, devices_)
476            if (device != NULL)
477                device->startCalibration();
478
479        internalState_ |= Calibrating;
480        enterState("calibrator");
481    }
482
483    //! Tells all devices to stop the calibration and evaluate it. Buffers are being cleared as well!
484    void InputManager::stopCalibration()
485    {
486        BOOST_FOREACH(InputDevice* device, devices_)
487            if (device != NULL)
488                device->stopCalibration();
489
490        // restore old input state
491        leaveState("calibrator");
492        internalState_ &= ~Calibrating;
493        // Clear buffers to prevent button hold events
494        this->clearBuffers();
495
496        COUT(0) << "Calibration has been stored." << std::endl;
497    }
498
499    //! Gets called by WindowEventListener upon focus change --> clear buffers
500    void InputManager::windowFocusChanged(bool bFocus)
501    {
502        this->clearBuffers();
503    }
504
505    std::pair<int, int> InputManager::getMousePosition() const
506    {
507        Mouse* mouse = static_cast<Mouse*>(devices_[InputDeviceEnumerator::Mouse]);
508        if (mouse != NULL)
509        {
510            const OIS::MouseState state = mouse->getOISDevice()->getMouseState();
511            return std::make_pair(state.X.abs, state.Y.abs);
512        }
513        else
514            return std::make_pair(0, 0);
515    }
516
517    // ############################################################
518    // #####                    Input States                  #####
519    // ##########                                        ##########
520    // ############################################################
521
522    InputState* InputManager::createInputState(const std::string& name, bool bAlwaysGetsInput, bool bTransparent, InputStatePriority priority)
523    {
524        if (name.empty())
525            return 0;
526        if (statesByName_.find(name) == statesByName_.end())
527        {
528            if (priority >= InputStatePriority::HighPriority || priority == InputStatePriority::Empty)
529            {
530                // Make sure we don't add two high priority states with the same priority
531                for (std::map<std::string, InputState*>::const_iterator it = this->statesByName_.begin();
532                    it != this->statesByName_.end(); ++it)
533                {
534                    if (it->second->getPriority() == priority)
535                    {
536                        COUT(2) << "Warning: Could not add an InputState with the same priority '"
537                            << static_cast<int>(priority) << "' != 0." << std::endl;
538                        return 0;
539                    }
540                }
541            }
542            InputState* state = new InputState(name, bAlwaysGetsInput, bTransparent, priority);
543            statesByName_[name] = state;
544
545            return state;
546        }
547        else
548        {
549            COUT(2) << "Warning: Could not add an InputState with the same name '" << name << "'." << std::endl;
550            return 0;
551        }
552    }
553
554    InputState* InputManager::getState(const std::string& name)
555    {
556        std::map<std::string, InputState*>::iterator it = statesByName_.find(name);
557        if (it != statesByName_.end())
558            return it->second;
559        else
560            return 0;
561    }
562
563    bool InputManager::enterState(const std::string& name)
564    {
565        // get pointer from the map with all stored handlers
566        std::map<std::string, InputState*>::const_iterator it = statesByName_.find(name);
567        if (it != statesByName_.end() && activeStates_.find(it->second->getPriority()) == activeStates_.end())
568        {
569            // exists and not active
570            if (it->second->getPriority() == 0)
571            {
572                // Get smallest possible priority between 1 and maxStateStackSize_s
573                for (std::map<int, InputState*>::reverse_iterator rit = activeStates_.rbegin();
574                    rit != activeStates_.rend(); ++rit)
575                {
576                    if (rit->first < InputStatePriority::HighPriority)
577                    {
578                        it->second->setPriority(rit->first + 1);
579                        break;
580                    }
581                }
582                // In case no normal handler was on the stack
583                if (it->second->getPriority() == 0)
584                    it->second->setPriority(1);
585            }
586            activeStates_[it->second->getPriority()] = it->second;
587            updateActiveStates();
588            it->second->entered();
589
590            return true;
591        }
592        return false;
593    }
594
595    bool InputManager::leaveState(const std::string& name)
596    {
597        if (name == "empty")
598        {
599            COUT(2) << "InputManager: Leaving the empty state is not allowed!" << std::endl;
600            return false;
601        }
602        // get pointer from the map with all stored handlers
603        std::map<std::string, InputState*>::const_iterator it = statesByName_.find(name);
604        if (it != statesByName_.end() && activeStates_.find(it->second->getPriority()) != activeStates_.end())
605        {
606            // exists and active
607
608            it->second->left();
609
610            activeStates_.erase(it->second->getPriority());
611            if (it->second->getPriority() < InputStatePriority::HighPriority)
612                it->second->setPriority(0);
613            updateActiveStates();
614
615            return true;
616        }
617        return false;
618    }
619
620    bool InputManager::destroyState(const std::string& name)
621    {
622        if (name == "empty")
623        {
624            COUT(2) << "InputManager: Removing the empty state is not allowed!" << std::endl;
625            return false;
626        }
627        std::map<std::string, InputState*>::iterator it = statesByName_.find(name);
628        if (it != statesByName_.end())
629        {
630            this->leaveState(name);
631            destroyStateInternal(it->second);
632
633            return true;
634        }
635        return false;
636    }
637
638    //! Destroys an InputState internally.
639    void InputManager::destroyStateInternal(InputState* state)
640    {
641        assert(state && this->activeStates_.find(state->getPriority()) == this->activeStates_.end());
642        statesByName_.erase(state->getName());
643        state->destroy();
644    }
645
646    bool InputManager::setMouseExclusive(const std::string& name, TriBool::Value value)
647    {
648        if (name == "empty")
649        {
650            COUT(2) << "InputManager: Changing the empty state is not allowed!" << std::endl;
651            return false;
652        }
653        std::map<std::string, InputState*>::iterator it = statesByName_.find(name);
654        if (it != statesByName_.end())
655        {
656            it->second->setMouseExclusive(value);
657            return true;
658        }
659        return false;
660    }
661}
Note: See TracBrowser for help on using the repository browser.