]> git.mxchange.org Git - flightgear.git/blob - src/Input/input.hxx
add <mod-meta> and <mod-super> XML elements for key bindings
[flightgear.git] / src / Input / input.hxx
1 // input.hxx -- handle user input from various sources.
2 //
3 // Written by David Megginson, started May 2001.
4 //
5 // Copyright (C) 2001 David Megginson, david@megginson.com
6 //
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.
11 //
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.
16 //
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.
20 //
21 // $Id$
22
23
24 #ifndef _INPUT_HXX
25 #define _INPUT_HXX
26
27 #ifndef __cplusplus                                                          
28 # error This library requires C++
29 #endif
30
31 #include <plib/js.h>
32 #include <plib/ul.h>
33
34 #include <simgear/compiler.h>
35
36 #include <simgear/misc/sg_path.hxx>
37 #include <simgear/structure/subsystem_mgr.hxx>
38 #include <simgear/structure/SGBinding.hxx>
39 #include <simgear/props/condition.hxx>
40 #include <simgear/props/props.hxx>
41 #include <simgear/scene/util/SGSceneUserData.hxx>
42
43 #include <Main/fg_os.hxx>
44 #include <Main/fg_props.hxx>
45 #include <Main/globals.hxx>
46
47 #include <map>
48 #include <list>
49 #include <vector>
50
51 SG_USING_STD(map);
52 SG_USING_STD(vector);
53
54
55 \f
56
57 #if defined( UL_WIN32 )
58 #define TGT_PLATFORM    "windows"
59 #elif defined ( UL_MAC_OSX )
60 #define TGT_PLATFORM    "mac"
61 #else
62 #define TGT_PLATFORM    "unix"
63 #endif
64
65
66 \f
67 ////////////////////////////////////////////////////////////////////////
68 // General input mapping support.
69 ////////////////////////////////////////////////////////////////////////
70
71
72 /**
73  * Generic input module.
74  *
75  * <p>This module is designed to handle input from multiple sources --
76  * keyboard, joystick, mouse, or even panel switches -- in a consistent
77  * way, and to allow users to rebind any of the actions at runtime.</p>
78  */
79 class FGInput : public SGSubsystem
80 {
81 public:
82   /**
83    * Default constructor.
84    */
85   FGInput ();
86
87   /**
88    * Destructor.
89    */
90   virtual ~FGInput();
91
92   //
93   // Implementation of SGSubsystem.
94   //
95   virtual void init ();
96   virtual void reinit ();
97   virtual void postinit ();
98   virtual void bind ();
99   virtual void unbind ();
100   virtual void update (double dt);
101   virtual void suspend ();
102   virtual void resume ();
103   virtual bool is_suspended () const;
104
105
106   /**
107    * Control whether this is the default module to receive events.
108    *
109    * The first input module created will set itself as the default
110    * automatically.
111    *
112    * @param status true if this should be the default module for
113    * events, false otherwise.
114    */
115   virtual void makeDefault (bool status = true);
116
117
118   /**
119    * Handle a single keystroke.
120    *
121    * @param k The integer key code, see Main/fg_os.hxx
122    * @param modifiers Modifier keys pressed (bitfield).
123    * @param x The mouse x position at the time of keypress.
124    * @param y The mouse y position at the time of keypress.
125    */
126   virtual void doKey (int k, int modifiers, int x, int y);
127
128
129   /**
130    * Handle a mouse click event.
131    *
132    * @param button The mouse button selected.
133    * @param updown Button status.
134    * @param x The X position of the mouse event, in screen coordinates.
135    * @param y The Y position of the mouse event, in screen coordinates.
136    */
137   virtual void doMouseClick (int button, int updown, int x, int y, bool mainWindow, const osgGA::GUIEventAdapter*);
138
139
140   /**
141    * Handle mouse motion.
142    *
143    * @param x The new mouse x position, in screen coordinates.
144    * @param y The new mouse y position, in screen coordinates.
145    */
146   virtual void doMouseMotion (int x, int y);
147
148
149 private:
150                                 // Constants
151   enum 
152   {
153     MAX_KEYS = 1024,
154     MAX_JOYSTICKS = 10,
155     MAX_JOYSTICK_AXES = _JS_MAX_AXES,
156     MAX_JOYSTICK_BUTTONS = 32,
157
158     MAX_MICE = 1,
159     MAX_MOUSE_BUTTONS = 8
160   };
161   struct mouse;
162   friend struct mouse;
163
164   typedef vector<SGSharedPtr<SGBinding> > binding_list_t;
165
166   /**
167    * Settings for a key or button.
168    */
169   struct button {
170     button ();
171     virtual ~button ();
172     bool is_repeatable;
173     float interval_sec;
174     float last_dt;
175     int last_state;
176     binding_list_t bindings[KEYMOD_MAX];
177   };
178
179
180   /**
181    * Settings for a single joystick axis.
182    */
183   struct axis {
184     axis ();
185     virtual ~axis ();
186     float last_value;
187     float tolerance;
188     binding_list_t bindings[KEYMOD_MAX];
189     float low_threshold;
190     float high_threshold;
191     struct button low;
192     struct button high;
193     float interval_sec;
194     double last_dt;
195   };
196
197
198   /**
199    * Settings for a joystick.
200    */
201   struct joystick {
202     joystick ();
203     virtual ~joystick ();
204     int jsnum;
205     jsJoystick * js;
206     int naxes;
207     int nbuttons;
208     axis * axes;
209     button * buttons;
210   };
211
212
213   /**
214    * Settings for a mouse mode.
215    */
216   struct mouse_mode {
217     mouse_mode ();
218     virtual ~mouse_mode ();
219     int cursor;
220     bool constrained;
221     bool pass_through;
222     button * buttons;
223     binding_list_t x_bindings[KEYMOD_MAX];
224     binding_list_t y_bindings[KEYMOD_MAX];
225   };
226
227
228   /**
229    * Settings for a mouse.
230    */
231   struct mouse {
232     mouse ();
233     virtual ~mouse ();
234     int x;
235     int y;
236     SGPropertyNode_ptr mode_node;
237     SGPropertyNode_ptr mouse_button_nodes[MAX_MOUSE_BUTTONS];
238     int nModes;
239     int current_mode;
240     double timeout;
241     int save_x;
242     int save_y;
243     mouse_mode * modes;
244   };
245
246
247   /**
248    * Initialize joystick bindings.
249    */
250   void _init_joystick ();
251
252
253   /**
254    * Scan directory recursively for "named joystick" configuration files,
255    * and read them into /input/joysticks/js-named[index]++.
256    */
257   void _scan_joystick_dir (SGPath *path, SGPropertyNode* node, int *index);
258
259
260   /**
261    * Initialize mouse bindings.
262    */
263   void _init_mouse ();
264
265
266   /**
267    * Initialize a single button.
268    */
269   inline void _init_button (const SGPropertyNode * node,
270                             button &b,
271                             const string name);
272
273   /**
274    * Initialize key bindings, as well as those joystick parts that
275    * depend on a working Nasal subsystem.
276    */
277   void _postinit_keyboard ();
278   void _postinit_joystick ();
279
280   /**
281    * Update the keyboard.
282    */
283   void _update_keyboard ();
284
285
286   /**
287    * Update the joystick.
288    */
289   void _update_joystick (double dt);
290
291
292   /**
293    * Update the mouse.
294    */
295   void _update_mouse (double dt);
296
297
298   /**
299    * Update a single button.
300    */
301   inline void _update_button (button &b, int modifiers, bool pressed,
302                               int x, int y);
303
304
305   /**
306    * Read bindings and modifiers.
307    */
308   void _read_bindings (const SGPropertyNode * node,
309                        binding_list_t * binding_list,
310                        int modifiers);
311
312   /**
313    * Look up the bindings for a key code.
314    */
315   const binding_list_t& _find_key_bindings (unsigned int k,
316                                             int modifiers);
317
318   button _key_bindings[MAX_KEYS];
319   joystick _joystick_bindings[MAX_JOYSTICKS];
320   mouse _mouse_bindings[MAX_MICE];
321
322   /**
323    * Nasal module name/namespace.
324    */
325   string _module;
326
327   /**
328    * List of currently pressed mouse button events
329    */
330   std::map<int, std::list<SGSharedPtr<SGPickCallback> > > _activePickCallbacks;
331
332   /**
333    * Key listener interface.
334    */
335   SGPropertyNode_ptr _key_event;
336   int  _key_code;
337   int  _key_modifiers;
338   bool _key_pressed;
339   bool _key_shift;
340   bool _key_ctrl;
341   bool _key_alt;
342   bool _key_meta;
343   bool _key_super;
344 };
345
346 #endif // _INPUT_HXX