]> git.mxchange.org Git - flightgear.git/commitdiff
I'm attaching diffs to add a new FGInput module to FlightGear
authorcurt <curt>
Wed, 23 May 2001 23:01:15 +0000 (23:01 +0000)
committercurt <curt>
Wed, 23 May 2001 23:01:15 +0000 (23:01 +0000)
(src/Input).  So far, FGInput replaces most of src/Main/keyboard.cxx
(I've left a tiny stub); in the very near future, it will also take
over control of the joystick, mouse (Norm permitting), and panel
instrument interactions, so that there is a single mechanism for
configuring all input devices.

The new format should be (close to) self-explanatory by looking at the
new base-package file keyboard.xml, which is now included by
preferences.xml (I'll do the same thing for the joystick when I have a
chance).  I have not managed to move all keybindings into this file
yet, but I've made a good start.  I'm including Tony in the recipient
list so that he can see how bindings can use an external XML file.

This patch also adds support for multiple bindings for a single key,
special keys (i.e. keypad and function keys), and key modifiers
(shift/alt/ctrl); special keys use the PUI convention of adding 256 to
the Glut key code.

Unfortunately, everything comes with a price; in this case, I have not
yet found a general mechanism for the old (hard-coded) modal bindings,
which behaved differently depending on the autopilot state (i.e. left
rudder or move AP heading left); with my patches, this functionality
disappears, but you can still adjust the autopilot using the panel or
the GUI input dialogs.

src/Main/Makefile.am
src/Main/fg_init.cxx
src/Main/fg_props.cxx
src/Main/fg_props.hxx
src/Main/keyboard.cxx
src/Makefile.am

index 15af75a39cbc3eac2cd6ef99c83766df3e3497df..6ec4a21f90f497756ac63170d7613c7a135244b3 100644 (file)
@@ -75,6 +75,7 @@ fgfs_LDADD = \
        $(top_builddir)/src/Objects/libObjects.a \
        $(top_builddir)/src/Time/libTime.a \
        $(WEATHER_LIBS) \
+       $(top_builddir)/src/Input/libInput.a \
        $(top_builddir)/src/Joystick/libJoystick.a \
        -lsgroute -lsgsky -lsgephem -lsgtiming -lsgio -lsgscreen \
        -lsgmath -lsgbucket -lsgdebug -lsgmagvar -lsgmisc -lsgxml \
index 3ffd176f4b78e8bfde868f931055237fa37a40d3..3765b09e9aa91b540859808b2b97dbfd221178bc 100644 (file)
@@ -80,6 +80,7 @@
 #include <FDM/LaRCsim.hxx>
 #include <FDM/MagicCarpet.hxx>
 #include <Include/general.hxx>
+#include <Input/input.hxx>
 #include <Joystick/joystick.hxx>
 #include <Objects/matlib.hxx>
 #include <Navaids/fixlist.hxx>
@@ -754,6 +755,14 @@ bool fgInitSubsystems( void ) {
     controls.bind();
 
 
+    ////////////////////////////////////////////////////////////////////
+    // Initialize the input subsystem.
+    ////////////////////////////////////////////////////////////////////
+
+    current_input.init();
+    current_input.bind();
+
+
     ////////////////////////////////////////////////////////////////////////
     // End of subsystem initialization.
     ////////////////////////////////////////////////////////////////////
index 3444e138b50035f9dc5c525e0542c0b006c00293..70f5ffb38e0d5c0359e488b52b0945891a9f0ef7 100644 (file)
@@ -1,8 +1,8 @@
-// fg_props.cxx -- support for
+// fg_props.cxx -- support for FlightGear properties.
 //
-// Written by David Megginson, started November 1999.
+// Written by David Megginson, started 2000.
 //
-// Copyright (C) 1999, 2000 David Megginson - david@megginson.com
+// Copyright (C) 2000, 2001 David Megginson - david@megginson.com
 //
 // This program is free software; you can redistribute it and/or
 // modify it under the terms of the GNU General Public License as
index 8a6c28bcddc374f90897e03c0717f7730da9b71e..9e794d384ce4738b064f9fdd339af11261e9af5f 100644 (file)
@@ -19,13 +19,28 @@ extern bool fgLoadFlight (istream &input);
 // Convenience functions for getting property values.
 ////////////////////////////////////////////////////////////////////////
 
+
+/**
+ * Get a property node.
+ *
+ * @param path The path of the node, relative to root.
+ * @param create true to create the node if it doesn't exist.
+ */
+inline SGPropertyNode * 
+fgGetNode (const string &path, bool create = false)
+{
+  return globals->get_props()->getNode(path, create);
+}
+
+
 /**
  * Get an SGValue pointer that can be queried repeatedly.
  *
  * If the property value is going to be accessed within the loop,
  * it is best to use this method for maximum efficiency.
  */
-inline SGValue * fgGetValue (const string &name, bool create = false)
+inline SGValue * 
+fgGetValue (const string &name, bool create = false)
 {
   return globals->get_props()->getValue(name, create);
 }
index c2dc81145e0de522441eb98da8dc959389ea77e2..7882c8ff25c9c91839c983e9c0087b1c5650a207 100644 (file)
 #  include <windows.h>                     
 #endif
 
-#include <simgear/compiler.h>
-
 #include <GL/glut.h>
-#include <GL/gl.h>
-
-#if defined(FX) && defined(XMESA)
-#include <GL/xmesa.h>
-#endif
-
-#include <stdio.h>
-#include <stdlib.h>
-
-#include STL_FSTREAM
-
-#include <plib/pu.h>           // plib include
-
-#include <simgear/constants.h>
-#include <simgear/debug/logstream.hxx>
-#include <simgear/misc/sg_path.hxx>
-
-#include <Aircraft/aircraft.hxx>
-#include <Autopilot/auto_gui.hxx>
-#include <Autopilot/newauto.hxx>
-#include <Cockpit/hud.hxx>
-#include <Cockpit/panel.hxx>
-#include <Cockpit/panel_io.hxx>
-#include <GUI/gui.h>
-#include <Scenery/scenery.hxx>
-#include <Scenery/tilemgr.hxx>
-#include <Objects/matlib.hxx>
-#include <Time/light.hxx>
-#include <Time/tmp.hxx>
-
-#ifndef FG_OLD_WEATHER
-#  include <WeatherCM/FGLocalWeatherDatabase.h>
-#else
-#  include <Weather/weather.hxx>
-#endif
 
-#include "bfi.hxx"
-#include "globals.hxx"
-#include "keyboard.hxx"
-#include "fg_props.hxx"
-#include "options.hxx"
-                               // From main.cxx
-extern void fgReshape( int width, int height );
+#include <plib/pu.h>
 
+#include <simgear/compiler.h>
 
-#ifdef BOOL
-#error A sloppy coder has defined BOOL as a macro!
-#undef BOOL
-#endif
+#include <Input/input.hxx>
 
 
 /**
- * Fire a user-defined key binding.
- *
- * <p>This function is temporary; eventually, all of the keyboard,
- * joystick, and mouse support should migrate into a common Input
- * module.</p>
- *
- * @param binding The property node for the binding.
+ * Construct the modifiers.
  */
-static void
-doBinding (const SGPropertyNode * binding)
+static inline int get_mods ()
 {
-  const string &action = binding->getStringValue("action", "");
-  const string &control = binding->getStringValue("control", "");
-  bool repeatable = binding->getBoolValue("repeatable", false);
-  int step = binding->getIntValue("step", 0.0);
-
-  if (control == "") {
-    SG_LOG(SG_INPUT, SG_ALERT, "No control specified for key "
-          << binding->getIndex());
-    return;
-  }
-
-  else if (action == "") {
-    SG_LOG(SG_INPUT, SG_ALERT, "No action specified for key "
-          << binding->getIndex());
-    return;
-  }
+  int glut_modifiers = glutGetModifiers();
+  int modifiers = 0;
 
-  else if (action == "switch") {
-    SG_LOG(SG_INPUT, SG_INFO, "Toggling value of " << control);
-    fgSetBool(control, !fgGetBool(control));
-  }
+  if (glut_modifiers & GLUT_ACTIVE_SHIFT)
+    modifiers |= FGInput::MOD_SHIFT;
+  if (glut_modifiers & GLUT_ACTIVE_CTRL)
+    modifiers |= FGInput::MOD_CTRL;
+  if (glut_modifiers & GLUT_ACTIVE_ALT)
+    modifiers |= FGInput::MOD_ALT;
 
-  else if (action == "adjust") {
-    const SGValue * step = binding->getValue("value");
-    if (step == 0) {
-      SG_LOG(SG_INPUT, SG_ALERT, "No step supplied for adjust action for key "
-            << binding->getIndex());
-      return;
-    }
-    SGValue * target = fgGetValue(control, true);
-                               // Use the target's type...
-    switch (target->getType()) {
-    case SGValue::BOOL:
-    case SGValue::INT:
-      target->setIntValue(target->getIntValue() + step->getIntValue());
-      break;
-    case SGValue::LONG:
-      target->setLongValue(target->getLongValue() + step->getLongValue());
-      break;
-    case SGValue::FLOAT:
-      target->setFloatValue(target->getFloatValue() + step->getFloatValue());
-      break;
-    case SGValue::DOUBLE:
-    case SGValue::UNKNOWN:     // treat unknown as a double
-      target->setDoubleValue(target->getDoubleValue()
-                            + step->getDoubleValue());
-      break;
-    case SGValue::STRING:
-      SG_LOG(SG_INPUT, SG_ALERT, "Failed attempt to adjust string property "
-            << control);
-      break;
-    }
-  }
-
-  else if (action == "assign") {
-    const SGValue * value = binding->getValue("value");
-    if (value == 0) {
-      SG_LOG(SG_INPUT, SG_ALERT, "No value supplied for assign action for key "
-            << binding->getIndex());
-      return;
-    }
-    SGValue * target = fgGetValue(control, true);
-                               // Use the target's type...
-    switch (target->getType()) {
-    case SGValue::BOOL:
-      target->setBoolValue(value->getBoolValue());
-      break;
-    case SGValue::INT:
-      target->setIntValue(value->getIntValue());
-      break;
-    case SGValue::LONG:
-      target->setLongValue(value->getLongValue());
-      break;
-    case SGValue::FLOAT:
-      target->setFloatValue(value->getFloatValue());
-      break;
-    case SGValue::DOUBLE:
-      target->setDoubleValue(value->getDoubleValue());
-      break;
-    case SGValue::STRING:
-      target->setStringValue(value->getStringValue());
-      break;
-    case SGValue::UNKNOWN:
-      target->setUnknownValue(value->getStringValue());
-      break;
-    }
-  }
-
-  else {
-    SG_LOG(SG_INPUT, SG_ALERT, "Unknown action " << action
-          << " for key " << binding->getIndex());
-  }
+  return modifiers;
 }
 
 
 /**
  * Keyboard event handler for Glut.
  *
+ * <p>Pass the value on to the FGInput module unless PUI wants it.</p>
+ *
  * @param k The integer value for the key pressed.
  * @param x (unused)
  * @param y (unused)
  */
-void GLUTkey(unsigned char k, int x, int y) {
-    float fov, tmp;
-    static bool winding_ccw = true;
-    int speed;
-
-                               // First, check for a user override.
-    const SGPropertyNode * binding = globals->get_props()
-      ->getNode("/input/keyboard/", true)->getChild("key", int(k));
-    if (binding != 0) {
-      doBinding(binding);
-      return;
-    }
-
-                               // Use the old, default actions.
-    FGInterface *f = current_aircraft.fdm_state;
-    FGViewer *v = globals->get_current_view();
-
-    SG_LOG( SG_INPUT, SG_DEBUG, "Key hit = " << k );
-    if ( puKeyboard(k, PU_DOWN) ) {
-       return;
-    }
-
-    if ( GLUT_ACTIVE_ALT && glutGetModifiers() ) {
-       SG_LOG( SG_INPUT, SG_DEBUG, " SHIFTED" );
-       switch (k) {
-       case 1: // Ctrl-A key
-           current_autopilot->set_AltitudeMode( 
-                  FGAutopilot::FG_ALTITUDE_LOCK );
-           current_autopilot->set_AltitudeEnabled(
-                 ! current_autopilot->get_AltitudeEnabled()
-               );
-           return;
-       case 7: // Ctrl-G key
-           current_autopilot->set_AltitudeMode( 
-                  FGAutopilot::FG_ALTITUDE_GS1 );
-           current_autopilot->set_AltitudeEnabled(
-                 ! current_autopilot->get_AltitudeEnabled()
-               );
-           return;
-       case 8: // Ctrl-H key
-           current_autopilot->set_HeadingMode(
-                 FGAutopilot::FG_TC_HEADING_LOCK );
-           current_autopilot->set_HeadingEnabled(
-                 ! current_autopilot->get_HeadingEnabled()
-               );
-           return;
-       case 14: // Ctrl-N key
-           current_autopilot->set_HeadingMode( 
-                  FGAutopilot::FG_HEADING_NAV1 );
-           current_autopilot->set_HeadingEnabled(
-                 ! current_autopilot->get_HeadingEnabled()
-               );
-           return;
-       case 18: // Ctrl-R key
-           // temporary
-           winding_ccw = !winding_ccw;
-           if ( winding_ccw ) {
-               glFrontFace ( GL_CCW );
-           } else {
-               glFrontFace ( GL_CW );
-           }
-           return;
-       case 19: // Ctrl-S key
-           current_autopilot->set_AutoThrottleEnabled(
-                 ! current_autopilot->get_AutoThrottleEnabled()
-               );
-           return;
-       case 20: // Ctrl-T key
-           current_autopilot->set_AltitudeMode( 
-                  FGAutopilot::FG_ALTITUDE_TERRAIN );
-           current_autopilot->set_AltitudeEnabled(
-                 ! current_autopilot->get_AltitudeEnabled()
-               );
-           return;
-       case 21: // Ctrl-U key
-           // add 1000' of emergency altitude.  Possibly good for 
-           // unflipping yourself :-)
-           {
-               double alt = cur_fdm_state->get_Altitude() + 1000;
-               fgFDMForceAltitude( fgGetString("/sim/flight-model"), 
-                                   alt * SG_FEET_TO_METER );
-           }
-           return;
-       case 49: // numeric keypad 1
-           v->set_goal_view_offset( SGD_PI * 0.75 );
-           return;
-       case 50: // numeric keypad 2
-           v->set_goal_view_offset( SGD_PI );
-           return;
-       case 51: // numeric keypad 3
-           v->set_goal_view_offset( SGD_PI * 1.25 );
-           return;
-       case 52: // numeric keypad 4
-           v->set_goal_view_offset( SGD_PI * 0.50 );
-           return;
-       case 54: // numeric keypad 6
-           v->set_goal_view_offset( SGD_PI * 1.50 );
-           return;
-       case 55: // numeric keypad 7
-           v->set_goal_view_offset( SGD_PI * 0.25 );
-           return;
-       case 56: // numeric keypad 8
-           v->set_goal_view_offset( 0.00 );
-           return;
-       case 57: // numeric keypad 9
-           v->set_goal_view_offset( SGD_PI * 1.75 );
-           return;
-       case 65: // A key
-           speed = fgGetInt("/sim/speed-up");
-           speed--;
-           if ( speed < 1 ) {
-               speed = 1;
-           }
-           fgSetInt("/sim/speed-up", speed);
-           return;
-       case 72: // H key
-           HUD_brightkey( true );
-           return;
-       case 73: // I key
-           // Minimal Hud
-           fgHUDInit2(&current_aircraft);
-           return;
-       case 77: // M key
-           globals->inc_warp( -60 );
-           fgUpdateSkyAndLightingParams();
-           return;
-       case 80: // P key
-           if (fgGetBool("/sim/panel/visibility"))
-             fgSetBool("/sim/panel/visibility", false);
-           else
-             fgSetBool("/sim/panel/visibility", true);
-           fgReshape(fgGetInt("/sim/startup/xsize"),
-                     fgGetInt("/sim/startup/ysize"));
-           break;
-       case 84: // T key
-           globals->inc_warp_delta( -30 );
-           fgUpdateSkyAndLightingParams();
-           return;
-       case 87: // W key
-#if defined(FX) && !defined(WIN32)
-           global_fullscreen = ( !global_fullscreen );
-#  if defined(XMESA_FX_FULLSCREEN) && defined(XMESA_FX_WINDOW)
-           XMesaSetFXmode( global_fullscreen ? 
-                           XMESA_FX_FULLSCREEN : XMESA_FX_WINDOW );
-#  endif
-#endif
-           return;
-       case 88: // X key
-           fov = globals->get_current_view()->get_fov();
-           fov *= 1.05;
-           if ( fov > FG_FOV_MAX ) {
-               fov = FG_FOV_MAX;
-           }
-           globals->get_current_view()->set_fov(fov);
-           // v->force_update_fov_math();
-           return;
-       case 90: // Z key
-#ifndef FG_OLD_WEATHER
-           tmp = WeatherDatabase->getWeatherVisibility();
-           tmp /= 1.10;
-           WeatherDatabase->setWeatherVisibility( tmp );
-#else
-           tmp = current_weather.get_visibility();   // in meters
-           tmp /= 1.10;
-           current_weather.set_visibility( tmp );
-#endif
-           return;
-       }
-    } else {
-       SG_LOG( SG_INPUT, SG_DEBUG, "" );
-       switch (k) {
-       case 50: // numeric keypad 2
-           if ( current_autopilot->get_AltitudeEnabled() ) {
-               current_autopilot->AltitudeAdjust( 100 );
-           } else {
-               controls.move_elevator(-0.05);
-           }
-           return;
-       case 56: // numeric keypad 8
-           if ( current_autopilot->get_AltitudeEnabled() ) {
-               current_autopilot->AltitudeAdjust( -100 );
-           } else {
-               controls.move_elevator(0.05);
-           }
-           return;
-       case 49: // numeric keypad 1
-           controls.move_elevator_trim(-0.001);
-           return;
-       case 55: // numeric keypad 7
-           controls.move_elevator_trim(0.001);
-           return;
-       case 52: // numeric keypad 4
-           controls.move_aileron(-0.05);
-           return;
-       case 54: // numeric keypad 6
-           controls.move_aileron(0.05);
-           return;
-       case 48: // numeric keypad Ins
-           if ( current_autopilot->get_HeadingEnabled() ) {
-               current_autopilot->HeadingAdjust( -1 );
-           } else {
-               controls.move_rudder(-0.05);
-           }
-           return;
-       case 13: // numeric keypad Enter
-           if ( current_autopilot->get_HeadingEnabled() ) {
-               current_autopilot->HeadingAdjust( 1 );
-           } else {
-               controls.move_rudder(0.05);
-           }
-           return;
-       case 53: // numeric keypad 5
-           controls.set_aileron(0.0);
-           controls.set_elevator(0.0);
-           controls.set_rudder(0.0);
-           return;
-       case 57: // numeric keypad 9 (Pg Up)
-           if ( current_autopilot->get_AutoThrottleEnabled() ) {
-               current_autopilot->AutoThrottleAdjust( 5 );
-           } else {
-               controls.move_throttle( FGControls::ALL_ENGINES, 0.01 );
-           }
-           return;
-       case 51: // numeric keypad 3 (Pg Dn)
-           if ( current_autopilot->get_AutoThrottleEnabled() ) {
-               current_autopilot->AutoThrottleAdjust( -5 );
-           } else {
-               controls.move_throttle( FGControls::ALL_ENGINES, -0.01 );
-           }
-           return;
-       case 91: // [ key
-           controls.move_flaps(-0.34);
-           SG_LOG( SG_INPUT, SG_INFO,
-                   "Set flaps to " << controls.get_flaps() );
-           return;
-       case 93: // ] key
-           controls.move_flaps(0.34);
-           SG_LOG( SG_INPUT, SG_INFO,
-                   "Set flaps to " << controls.get_flaps() );
-           return;
-       case 97: // a key
-           speed = fgGetInt("/sim/speed-up");
-           speed++;
-           fgSetInt("/sim/speed-up", speed);
-           return;
-       case 98: // b key
-           int b_ret;
-           double b_set;
-           b_ret = int( controls.get_brake( 0 ) );
-           b_set = double(!b_ret);
-           controls.set_brake( FGControls::ALL_WHEELS, b_set);
-           return;
-       case 44: // , key
-           if (controls.get_brake(0) > 0.0) {
-               controls.set_brake(0, 0.0);
-           } else {
-               controls.set_brake(0, 1.0);
-           }
-           return;
-       case 46: // . key
-           if (controls.get_brake(1) > 0.0) {
-               controls.set_brake(1, 0.0);
-           } else {
-               controls.set_brake(1, 1.0);
-           }
-           return;
-       case 104: // h key
-           HUD_masterswitch( true );
-           return;
-       case 105: // i key
-           fgHUDInit(&current_aircraft);  // normal HUD
-           return;
-       case 109: // m key
-           globals->inc_warp( 60 );
-           fgUpdateSkyAndLightingParams();
-           return;
-       case 112: // p key
-           globals->set_freeze( ! globals->get_freeze() );
-
-           {
-               SGBucket p( f->get_Longitude() * SGD_RADIANS_TO_DEGREES,
-                           f->get_Latitude() * SGD_RADIANS_TO_DEGREES );
-               SGPath tile_path( globals->get_fg_root() );
-               tile_path.append( "Scenery" );
-               tile_path.append( p.gen_base_path() );
-               tile_path.append( p.gen_index_str() );
-
-               // printf position and attitude information
-               printf( "Lon = %.6f  Lat = %.6f  Ground = %.2f  Alt = %.2f\n",
-                       f->get_Longitude() * SGD_RADIANS_TO_DEGREES,
-                       f->get_Latitude() * SGD_RADIANS_TO_DEGREES,
-                       scenery.cur_elev,
-                       f->get_Altitude() * SG_FEET_TO_METER );
-               printf( "Heading = %.2f  Roll = %.2f  Pitch = %.2f\n",
-                       f->get_Psi() * SGD_RADIANS_TO_DEGREES,
-                       f->get_Phi() * SGD_RADIANS_TO_DEGREES,
-                       f->get_Theta() * SGD_RADIANS_TO_DEGREES );
-
-#if 0
-               SG_LOG( SG_INPUT, SG_INFO,
-                       "Lon = " << f->get_Longitude() * SGD_RADIANS_TO_DEGREES
-                       << "  Lat = " << f->get_Latitude() * SGD_RADIANS_TO_DEGREES
-                       << "  Altitude = " << f->get_Altitude() * SG_FEET_TO_METER
-                       );
-               SG_LOG( SG_INPUT, SG_INFO,
-                       "Heading = " << f->get_Psi() * SGD_RADIANS_TO_DEGREES 
-                       << "  Roll = " << f->get_Phi() * SGD_RADIANS_TO_DEGREES
-                       << "  Pitch = " << f->get_Theta() * SGD_RADIANS_TO_DEGREES );
-#endif
-
-               SG_LOG( SG_INPUT, SG_INFO, tile_path.c_str());
-           }
-           return;
-       case 116: // t key
-           globals->inc_warp_delta( 30 );
-           fgUpdateSkyAndLightingParams();
-           return;
-       case 118: // v key
-           // handles GUI state as well as Viewer LookAt Direction
-           CenterView();
-           globals->set_current_view( globals->get_viewmgr()->next_view() );
-           fgReshape( fgGetInt("/sim/startup/xsize"),
-                      fgGetInt("/sim/startup/ysize") );
-           return;
-       case 120: // x key
-           fov = globals->get_current_view()->get_fov();
-           fov /= 1.05;
-           if ( fov < FG_FOV_MIN ) {
-               fov = FG_FOV_MIN;
-           }
-           globals->get_current_view()->set_fov(fov);
-           // v->force_update_fov_math();
-           return;
-       case 122: // z key
-#ifndef FG_OLD_WEATHER
-           tmp = WeatherDatabase->getWeatherVisibility();
-           tmp *= 1.10;
-           WeatherDatabase->setWeatherVisibility( tmp );
-#else
-           tmp = current_weather.get_visibility();   // in meters
-           tmp *= 1.10;
-           current_weather.set_visibility( tmp );
-#endif
-           return;
-       case 27: // ESC
-           // if( fg_DebugOutput ) {
-           //   fclose( fg_DebugOutput );
-           // }
-           SG_LOG( SG_INPUT, SG_ALERT, 
-                   "Program exit requested." );
-           ConfirmExitDialog();
-           return;
-       }
-    }
+void GLUTkey(unsigned char k, int x, int y)
+{
+                               // Give PUI a chance to grab it first.
+  if (!puKeyboard(k, PU_DOWN))
+                               // This is problematic; it allows
+                               // (say) P and [SHIFT]P to be
+                               // distinguished, but is that a good
+                               // idea?
+    current_input.doKey(k, get_mods(), x, y);
 }
 
 
-// Handle "special" keyboard events
-void GLUTspecialkey(int k, int x, int y) {
-    FGViewer *v = globals->get_current_view();
-
-    SG_LOG( SG_INPUT, SG_DEBUG, "Special key hit = " << k );
-
-    if ( puKeyboard(k + PU_KEY_GLUT_SPECIAL_OFFSET, PU_DOWN) ) {
-       return;
-    }
-
-    if ( GLUT_ACTIVE_SHIFT && glutGetModifiers() ) {
-       SG_LOG( SG_INPUT, SG_DEBUG, " SHIFTED" );
-       switch (k) {
-       case GLUT_KEY_F1: {
-           ifstream input("fgfs.sav");
-           if (input.good() && fgLoadFlight(input)) {
-               input.close();
-               SG_LOG(SG_INPUT, SG_INFO, "Restored flight from fgfs.sav");
-           } else {
-               SG_LOG(SG_INPUT, SG_ALERT, "Cannot load flight from fgfs.sav");
-           }
-           return;
-       }
-       case GLUT_KEY_F2: {
-           SG_LOG(SG_INPUT, SG_INFO, "Saving flight");
-           cerr << "Opening output stream" << endl;
-           ofstream output("fgfs.sav");
-           cerr << "output stream opened" << endl;
-           if (output.good() && fgSaveFlight(output)) {
-               output.close();
-               SG_LOG(SG_INPUT, SG_INFO, "Saved flight to fgfs.sav");
-           } else {
-               SG_LOG(SG_INPUT, SG_ALERT, "Cannot save flight to fgfs.sav");
-           }
-           return;
-       }
-       case GLUT_KEY_F3: {
-            string panel_path =
-                fgGetString("/sim/panel/path", "Panels/Default/default.xml");
-            FGPanel * new_panel = fgReadPanel(panel_path);
-            if (new_panel == 0) {
-                SG_LOG(SG_INPUT, SG_ALERT,
-                       "Error reading new panel from " << panel_path);
-                return;
-            }
-            SG_LOG(SG_INPUT, SG_INFO, "Loaded new panel from " << panel_path);
-            current_panel->unbind();
-            delete current_panel;
-            current_panel = new_panel;
-            return;
-       }
-       case GLUT_KEY_F4: {
-            SGPath props_path(globals->get_fg_root());
-            props_path.append("preferences.xml");
-            SG_LOG(SG_INPUT, SG_INFO, "Rereading global preferences");
-            if (!readProperties(props_path.str(), globals->get_props())) {
-                SG_LOG(SG_INPUT, SG_ALERT,
-                       "Failed to reread global preferences from "
-                       << props_path.str());
-            } else {
-                SG_LOG(SG_INPUT, SG_INFO, "Finished Reading global preferences");
-            }
-            return;
-       }
-       case GLUT_KEY_F5: {
-            current_panel->setYOffset(current_panel->getYOffset() - 5);
-            fgReshape(fgGetInt("/sim/startup/xsize"),
-                      fgGetInt("/sim/startup/ysize"));
-            return;
-       }
-       case GLUT_KEY_F6: {
-            current_panel->setYOffset(current_panel->getYOffset() + 5);
-            fgReshape(fgGetInt("/sim/startup/xsize"),
-                      fgGetInt("/sim/startup/ysize"));
-            return;
-       }
-       case GLUT_KEY_F7: {
-            current_panel->setXOffset(current_panel->getXOffset() - 5);
-            return;
-       }
-       case GLUT_KEY_F8: {
-            current_panel->setXOffset(current_panel->getXOffset() + 5);
-            return;
-       }
-        // case GLUT_KEY_F9: {
-        //     return;
-        // }
-        case GLUT_KEY_F10: {
-            fgToggleFDMdataLogging();
-            return;
-        }
-        // case GLUT_KEY_F11: {
-        //     return;
-        // }
-        // case GLUT_KEY_F12: {
-        //     return;
-        // }
-       case GLUT_KEY_END: // numeric keypad 1
-           v->set_goal_view_offset( SGD_PI * 0.75 );
-           return;
-       case GLUT_KEY_DOWN: // numeric keypad 2
-           v->set_goal_view_offset( SGD_PI );
-           return;
-       case GLUT_KEY_PAGE_DOWN: // numeric keypad 3
-           v->set_goal_view_offset( SGD_PI * 1.25 );
-           return;
-       case GLUT_KEY_LEFT: // numeric keypad 4
-           v->set_goal_view_offset( SGD_PI * 0.50 );
-           return;
-       case GLUT_KEY_RIGHT: // numeric keypad 6
-           v->set_goal_view_offset( SGD_PI * 1.50 );
-           return;
-       case GLUT_KEY_HOME: // numeric keypad 7
-           v->set_goal_view_offset( SGD_PI * 0.25 );
-           return;
-       case GLUT_KEY_UP: // numeric keypad 8
-           v->set_goal_view_offset( 0.00 );
-           return;
-       case GLUT_KEY_PAGE_UP: // numeric keypad 9
-           v->set_goal_view_offset( SGD_PI * 1.75 );
-           return;
-       }
-    } else {
-        SG_LOG( SG_INPUT, SG_DEBUG, "" );
-       switch (k) {
-       case GLUT_KEY_F2: // F2 Reload Tile Cache...
-           {
-               bool freeze = globals->get_freeze();
-               SG_LOG(SG_INPUT, SG_INFO, "ReIniting TileCache");
-               if ( !freeze ) 
-                   globals->set_freeze( true );
-               BusyCursor(0);
-               if ( global_tile_mgr.init() ) {
-                   // Load the local scenery data
-                   global_tile_mgr.update( 
-                       cur_fdm_state->get_Longitude() * SGD_RADIANS_TO_DEGREES,
-                       cur_fdm_state->get_Latitude() * SGD_RADIANS_TO_DEGREES );
-               } else {
-                   SG_LOG( SG_GENERAL, SG_ALERT, 
-                           "Error in Tile Manager initialization!" );
-                   exit(-1);
-               }
-               BusyCursor(1);
-               if ( !freeze )
-                  globals->set_freeze( false );
-               return;
-           }
-       case GLUT_KEY_F3: // F3 Take a screen shot
-           fgDumpSnapShot();
-           return;
-        case GLUT_KEY_F4: // F4 Update lighting manually
-           fgUpdateSkyAndLightingParams();
-            return;
-        case GLUT_KEY_F6: // F6 toggles Autopilot target location
-           if ( current_autopilot->get_HeadingMode() !=
-                FGAutopilot::FG_HEADING_WAYPOINT ) {
-               current_autopilot->set_HeadingMode(
-                   FGAutopilot::FG_HEADING_WAYPOINT );
-               current_autopilot->set_HeadingEnabled( true );
-           } else {
-               current_autopilot->set_HeadingMode(
-                   FGAutopilot::FG_TC_HEADING_LOCK );
-           }
-           return;
-       case GLUT_KEY_F8: {// F8 toggles fog ... off fastest nicest...
-           const string &fog = fgGetString("/sim/rendering/fog");
-           if (fog == "disabled") {
-             fgSetString("/sim/rendering/fog", "fastest");
-             SG_LOG(SG_INPUT, SG_INFO, "Fog enabled, hint=fastest");
-           } else if (fog == "fastest") {
-             fgSetString("/sim/rendering/fog", "nicest");
-             SG_LOG(SG_INPUT, SG_INFO, "Fog enabled, hint=nicest");
-           } else if (fog == "nicest") {
-             fgSetString("/sim/rendering/fog", "disabled");
-             SG_LOG(SG_INPUT, SG_INFO, "Fog disabled");
-           } else {
-             fgSetString("/sim/rendering/fog", "disabled");
-             SG_LOG(SG_INPUT, SG_ALERT, "Unrecognized fog type "
-                    << fog << ", changed to 'disabled'");
-           }
-           return;
-       }
-       case GLUT_KEY_F9: // F9 toggles textures on and off...
-           SG_LOG( SG_INPUT, SG_INFO, "Toggling texture" );
-           if ( fgGetBool("/sim/rendering/textures")) {
-               fgSetBool("/sim/rendering/textures", false);
-               material_lib.set_step( 1 );
-           } else {
-               fgSetBool("/sim/rendering/textures", true);
-               material_lib.set_step( 0 );
-           }
-           return;
-       case GLUT_KEY_F10: // F10 toggles menu on and off...
-           SG_LOG(SG_INPUT, SG_INFO, "Invoking call back function");
-           guiToggleMenu();
-           return;
-       case GLUT_KEY_F11: // F11 Altitude Dialog.
-           SG_LOG(SG_INPUT, SG_INFO, "Invoking Altitude call back function");
-           NewAltitude( NULL );
-           return;
-       case GLUT_KEY_F12: // F12 Heading Dialog...
-           SG_LOG(SG_INPUT, SG_INFO, "Invoking Heading call back function");
-           NewHeading( NULL );
-           return;
-       case GLUT_KEY_UP:
-           if ( current_autopilot->get_AltitudeEnabled() ) {
-               current_autopilot->AltitudeAdjust( -100 );
-           } else {
-               controls.move_elevator(0.05);
-           }
-           return;
-       case GLUT_KEY_DOWN:
-           if ( current_autopilot->get_AltitudeEnabled() ) {
-               current_autopilot->AltitudeAdjust( 100 );
-           } else {
-               controls.move_elevator(-0.05);
-           }
-           return;
-       case GLUT_KEY_LEFT:
-           controls.move_aileron(-0.05);
-           return;
-       case GLUT_KEY_RIGHT:
-           controls.move_aileron(0.05);
-           return;
-       case GLUT_KEY_HOME: // numeric keypad 1
-           controls.move_elevator_trim(0.001);
-           return;
-       case GLUT_KEY_END: // numeric keypad 7
-           controls.move_elevator_trim(-0.001);
-           return;
-       case GLUT_KEY_INSERT: // numeric keypad Ins
-           if ( current_autopilot->get_HeadingEnabled() ) {
-               current_autopilot->HeadingAdjust( -1 );
-           } else {
-               controls.move_rudder(-0.05);
-           }
-           return;
-       case 13: // numeric keypad Enter
-           if ( current_autopilot->get_HeadingEnabled() ) {
-               current_autopilot->HeadingAdjust( 1 );
-           } else {
-               controls.move_rudder(0.05);
-           }
-           return;
-       case 53: // numeric keypad 5
-           controls.set_aileron(0.0);
-           controls.set_elevator(0.0);
-           controls.set_rudder(0.0);
-           return;
-       case GLUT_KEY_PAGE_UP: // numeric keypad 9 (Pg Up)
-           if ( current_autopilot->get_AutoThrottleEnabled() ) {
-               current_autopilot->AutoThrottleAdjust( 5 );
-           } else {
-               controls.move_throttle( FGControls::ALL_ENGINES, 0.01 );
-           }
-           return;
-       case GLUT_KEY_PAGE_DOWN: // numeric keypad 3 (Pg Dn)
-           if ( current_autopilot->get_AutoThrottleEnabled() ) {
-               current_autopilot->AutoThrottleAdjust( -5 );
-           } else {
-               controls.move_throttle( FGControls::ALL_ENGINES, -0.01 );
-           }
-           return;
-       }
-    }
+/**
+ * Special key handler for Glut.
+ *
+ * <p>Pass the value on to the FGInput module unless PUI wants it.
+ * The key value will have 256 added to it.</p>
+ *
+ * @param k The integer value for the key pressed (will have 256 added
+ * to it).
+ * @param x (unused)
+ * @param y (unused)
+ */
+void GLUTspecialkey(int k, int x, int y)
+{
+                               // Give PUI a chance to grab it first.
+  if (!puKeyboard(k + PU_KEY_GLUT_SPECIAL_OFFSET, PU_DOWN))
+    current_input.doKey(k + 256, get_mods(), x, y);
 }
 
 
+// end of keyboard.cxx
index c3eac2460bf16bfb22616c260c4e4c1b9644be17..776ff82883e2430a39b44b7ea7f87477df01571b 100644 (file)
@@ -19,6 +19,7 @@ SUBDIRS = \
         Controls \
         FDM \
         GUI \
+       Input \
         Joystick \
        Navaids \
         $(NETWORK_DIRS) \