1 // FGEventInput.hxx -- handle event driven input devices
3 // Written by Torsten Dreyer, started July 2009
5 // Copyright (C) 2009 Torsten Dreyer, Torsten (at) t3r _dot_ de
7 // This program is free software; you can redistribute it and/or
8 // modify it under the terms of the GNU General Public License as
9 // published by the Free Software Foundation; either version 2 of the
10 // License, or (at your option) any later version.
12 // This program is distributed in the hope that it will be useful, but
13 // WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 // General Public License for more details.
17 // You should have received a copy of the GNU General Public License
18 // along with this program; if not, write to the Free Software
19 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
23 #ifndef __FGEVENTINPUT_HXX
24 #define __FGEVENTINPUT_HXX
26 #include "FGCommonInput.hxx"
30 #include "FGButton.hxx"
31 #include "FGDeviceConfigurationMap.hxx"
32 #include <simgear/structure/subsystem_mgr.hxx>
35 * A base structure for event data.
36 * To be extended for O/S specific implementation data
39 FGEventData( double aValue, double aDt, int aModifiers ) : modifiers(aModifiers), value(aValue), dt(aDt) {}
45 class FGEventSetting : public SGReferenced {
47 FGEventSetting( SGPropertyNode_ptr base );
52 * access for the value property
58 SGPropertyNode_ptr valueNode;
59 SGSharedPtr<const SGCondition> condition;
62 typedef SGSharedPtr<FGEventSetting> FGEventSetting_ptr;
63 typedef std::vector<FGEventSetting_ptr> setting_list_t;
66 * A wrapper class for a configured event.
69 * <desc>Change the view pitch</desc>
70 * <name>rel-x-rotate</name>
72 * <command>property-adjust</command>
73 * <property>sim/current-view/pitch-offset-deg</property>
74 * <factor type="double">0.01</factor>
75 * <min type="double">-90.0</min>
76 * <max type="double">90.0</max>
77 * <wrap type="bool">false</wrap>
87 class FGInputEvent : public SGReferenced,FGCommonInput {
91 * Constructor for the class. The arg node shall point
92 * to the property corresponding to the <event> node
94 FGInputEvent( FGInputDevice * device, SGPropertyNode_ptr node );
95 virtual ~FGInputEvent();
98 * dispatch the event value through all bindings
100 virtual void fire( FGEventData & eventData );
103 * access for the name property
105 std::string GetName() const { return name; }
108 * access for the description property
110 std::string GetDescription() const { return desc; }
112 virtual void update( double dt );
114 static FGInputEvent * NewObject( FGInputDevice * device, SGPropertyNode_ptr node );
117 virtual void fire( SGBinding * binding, FGEventData & eventData );
118 /* A more or less meaningfull description of the event */
121 /* One of the predefined names of the event */
124 /* A list of SGBinding objects */
125 binding_list_t bindings[KEYMOD_MAX];
127 /* A list of FGEventSetting objects */
128 setting_list_t settings;
130 /* A pointer to the associated device */
131 FGInputDevice * device;
135 double lastSettingValue;
138 class FGButtonEvent : public FGInputEvent {
140 FGButtonEvent( FGInputDevice * device, SGPropertyNode_ptr node );
141 virtual void fire( FGEventData & eventData );
148 class FGAxisEvent : public FGInputEvent {
150 FGAxisEvent( FGInputDevice * device, SGPropertyNode_ptr node );
151 void SetMaxRange( double value ) { maxRange = value; }
152 void SetMinRange( double value ) { minRange = value; }
153 void SetRange( double min, double max ) { minRange = min; maxRange = max; }
155 virtual void fire( FGEventData & eventData );
162 double highThreshold;
166 class FGRelAxisEvent : public FGAxisEvent {
168 FGRelAxisEvent( FGInputDevice * device, SGPropertyNode_ptr node );
170 virtual void fire( SGBinding * binding, FGEventData & eventData );
173 class FGAbsAxisEvent : public FGAxisEvent {
175 FGAbsAxisEvent( FGInputDevice * device, SGPropertyNode_ptr node ) : FGAxisEvent( device, node ) {}
177 virtual void fire( SGBinding * binding, FGEventData & eventData );
180 typedef class SGSharedPtr<FGInputEvent> FGInputEvent_ptr;
183 * A abstract class implementing basic functionality of input devices for
184 * all operating systems. This is the base class for the O/S-specific
185 * implementation of input device handlers
187 class FGInputDevice : public SGReferenced {
189 FGInputDevice() : debugEvents(false), grab(false) {}
190 FGInputDevice( std::string aName ) : name(aName) {}
192 virtual ~FGInputDevice();
194 virtual void Open() = 0;
195 virtual void Close() = 0;
197 virtual void Send( const char * eventName, double value ) = 0;
199 inline void Send( const std::string & eventName, double value ) {
200 Send( eventName.c_str(), value );
203 virtual const char * TranslateEventName( FGEventData & eventData ) = 0;
206 void SetName( std::string name );
207 std::string & GetName() { return name; }
209 void HandleEvent( FGEventData & eventData );
211 void AddHandledEvent( FGInputEvent_ptr handledEvent ) {
212 if( handledEvents.count( handledEvent->GetName() ) == 0 )
213 handledEvents[handledEvent->GetName()] = handledEvent;
216 virtual void Configure( SGPropertyNode_ptr deviceNode );
218 virtual void update( double dt );
220 bool GetDebugEvents () const { return debugEvents; }
222 bool GetGrab() const { return grab; }
224 const std::string & GetNasalModule() const { return nasalModule; }
227 // A map of events, this device handles
228 std::map<std::string,FGInputEvent_ptr> handledEvents;
230 // the device has a name to be recognized
233 // print out events comming in from the device
237 // grab the device exclusively, if O/S supports this
238 // so events are not sent to other applications
241 SGPropertyNode_ptr deviceNode;
242 std::string nasalModule;
245 typedef SGSharedPtr<FGInputDevice> FGInputDevice_ptr;
249 * The Subsystem for the event input device
251 class FGEventInput : public SGSubsystem,FGCommonInput {
254 virtual ~FGEventInput();
256 virtual void postinit();
257 virtual void update( double dt );
259 const static unsigned MAX_DEVICES = 1000;
260 const static unsigned INVALID_DEVICE_INDEX = MAX_DEVICES + 1;
262 static const char * PROPERTY_ROOT;
264 unsigned AddDevice( FGInputDevice * inputDevice );
265 void RemoveDevice( unsigned index );
267 std::map<int,FGInputDevice*> input_devices;
268 FGDeviceConfigurationMap configMap;
270 SGPropertyNode_ptr nasalClose;