-fntTexFont *guiFntHandle = 0;
-
-static puMenuBar *mainMenuBar = 0;
-//static puButton *hideMenuButton = 0;
-
-static puDialogBox *dialogBox = 0;
-static puFrame *dialogFrame = 0;
-static puText *dialogBoxMessage = 0;
-static puOneShot *dialogBoxOkButton = 0;
-
-
-static puDialogBox *YNdialogBox = 0;
-static puFrame *YNdialogFrame = 0;
-static puText *YNdialogBoxMessage = 0;
-static puOneShot *YNdialogBoxOkButton = 0;
-static puOneShot *YNdialogBoxNoButton = 0;
-
-static char msg_OK[] = "OK";
-static char msg_NO[] = "NO";
-static char msg_YES[] = "YES";
-static char msg_CANCEL[] = "Cancel";
-static char msg_RESET[] = "Reset";
-
-char *gui_msg_OK; // "OK"
-char *gui_msg_NO; // "NO"
-char *gui_msg_YES; // "YES"
-char *gui_msg_CANCEL; // "CANCEL"
-char *gui_msg_RESET; // "RESET"
-
-static char global_dialog_string[256];
-
-// from autopilot.cxx
-// extern void NewAltitude( puObject *cb );
-// extern void NewHeading( puObject *cb );
-// extern void fgAPAdjust( puObject * );
-// extern void NewTgtAirport( puObject *cb );
-// bool fgAPTerrainFollowEnabled( void );
-// bool fgAPAltitudeEnabled( void );
-// bool fgAPHeadingEnabled( void );
-// bool fgAPWayPointEnabled( void );
-// bool fgAPAutoThrottleEnabled( void );
-
-// from cockpit.cxx
-extern void fgLatLonFormatToggle( puObject *);
-
-/* --------------------------------------------------------------------
-Mouse stuff
----------------------------------------------------------------------*/
-
-static int _mX = 0;
-static int _mY = 0;
-static int _savedX = 0;
-static int _savedY = 0;
-static int last_buttons = 0 ;
-static int mouse_active = 0;
-static int menu_on = 0;
-static int mouse_joystick_control = 0;
-
-//static time_t mouse_off_time;
-//static int mouse_timed_out;
-
-// to allow returning to previous view
-// on second left click in MOUSE_VIEW mode
-// This has file scope so that it can be reset
-// if the little rodent is moved NHV
-static int _mVtoggle;
-
-// we break up the glutGetModifiers return mask
-// once per loop and stash what we need in these
-static int glut_active_shift;
-static int glut_active_ctrl;
-static int glut_active_alt;
-
-static float lastquat[4];
-static float curquat[4];
-static float _quat0[4];
-float quat_mat[4][4];
-
-// uncomment this for view to exactly follow mouse in MOUSE_VIEW mode
-// else smooth out the view panning to .01 radian per frame
-// see view_offset smoothing mechanism in main.cxx
-#define NO_SMOOTH_MOUSE_VIEW
-
-// uncomment following to
-#define RESET_VIEW_ON_LEAVING_MOUSE_VIEW
-
-/* --------------------------------------------------------------------
-Support for mouse as control yoke (david@megginson.com)
-
-- right button toggles between pointer and yoke
-- horizontal drag with no buttons moves ailerons
-- vertical drag with no buttons moves elevators
-- horizontal drag with left button moves brakes (left=on)
-- vertical drag with left button moves throttle (up=more)
-- horizontal drag with middle button moves rudder
-- vertical drag with middle button moves trim
-
-For the *_sensitivity variables, a lower number means more sensitive.
-
-TODO: figure out how to keep pointer from leaving window in yoke mode.
-TODO: add thresholds and null zones
-TODO: sensitivity should be configurable at user option.
-TODO: allow differential braking (this will be useful if FlightGear
- ever supports tail-draggers like the DC-3)
----------------------------------------------------------------------*/
-
-typedef enum {
- MOUSE_POINTER,
- MOUSE_YOKE,
- MOUSE_VIEW
-} MouseMode;
-
-MouseMode mouse_mode = MOUSE_POINTER;
-
-static double aileron_sensitivity = 1.0/500.0;
-static double elevator_sensitivity = 1.0/500.0;
-static double brake_sensitivity = 1.0/250.0;
-static double throttle_sensitivity = 1.0/250.0;
-static double rudder_sensitivity = 1.0/500.0;
-static double trim_sensitivity = 1.0/1000.0;
-
-static inline void Quat0( void ) {
- curquat[0] = _quat0[0];
- curquat[1] = _quat0[1];
- curquat[2] = _quat0[2];
- curquat[3] = _quat0[3];
-}
-
-static inline int left_button( void ) {
- return( last_buttons & (1 << GLUT_LEFT_BUTTON) );
-}
-
-static inline int middle_button( void ) {
- return( last_buttons & (1 << GLUT_MIDDLE_BUTTON) );
-}
-
-static inline int right_button( void ) {
- return( last_buttons & (1 << GLUT_RIGHT_BUTTON) );
-}
-
-static inline void TurnCursorOn( void )
-{
- mouse_active = ~0;
-#if defined(WIN32_CURSOR_TWEAKS)
- switch (mouse_mode) {
- case MOUSE_POINTER:
- glutSetCursor(GLUT_CURSOR_INHERIT);
- break;
- case MOUSE_YOKE:
- glutSetCursor(GLUT_CURSOR_CROSSHAIR);
- break;
- case MOUSE_VIEW:
- glutSetCursor(GLUT_CURSOR_LEFT_RIGHT);
- break;
- }
-#endif
-#if defined(X_CURSOR_TWEAKS)
- glutWarpPointer( current_view.get_winWidth()/2, current_view.get_winHeight()/2);
-#endif
-}
-
-static inline void TurnCursorOff( void )
-{
- mouse_active = 0;
-#if defined(WIN32_CURSOR_TWEAKS)
- glutSetCursor(GLUT_CURSOR_NONE);
-#elif defined(X_CURSOR_TWEAKS)
- glutWarpPointer( current_view.get_winWidth(), current_view.get_winHeight());
-#endif
-}
-
-void maybeToggleMouse( void )
-{
-#if defined(WIN32_CURSOR_TWEAKS)
- static int first_time = ~0;
- static int mouse_changed = 0;
-
- if ( first_time ) {
- if(!mouse_active) {
- mouse_changed = ~mouse_changed;
- TurnCursorOn();
- }
- } else {
- if( mouse_mode != MOUSE_POINTER )
- return;
- if( mouse_changed ) {
- mouse_changed = ~mouse_changed;
- if(mouse_active) {
- TurnCursorOff();
- }
- }
- }
- first_time = ~first_time;
-#endif // #ifdef WIN32
-}
-
-// Call with FALSE to init and TRUE to restore
-void BusyCursor( int restore )
-{
- static GLenum cursor = (GLenum) 0;
- if( restore ) {
- glutSetCursor(cursor);
- } else {
- cursor = (GLenum) glutGet( (GLenum) GLUT_WINDOW_CURSOR );
-#if defined(WIN32_CURSOR_TWEAKS)
- TurnCursorOn();
-#endif
- glutSetCursor( GLUT_CURSOR_WAIT );
- }
-}
-
-int guiGetMouseButton(void)
-{
- return last_buttons;
-}
-
-void guiGetMouse(int *x, int *y)
-{
- *x = _mX;
- *y = _mY;
-};
-
-void guiMotionFunc ( int x, int y )
-{
- int ww, wh, need_warp = 0;
- float W, H;
- double offset;
-// FGTime *t = FGTime::cur_time_params;
-// if( mouse_timed_out ) {
-// if( t->get_cur_time() > mouse_off_time ) {
-// moused_timed_out = 0;
-// TurnCursorOn();
-// glutPostRedisplay () ;
-// }
-// }
-
- if (mouse_mode == MOUSE_POINTER) {
- puMouse ( x, y ) ;
- glutPostRedisplay () ;
- } else {
- if( x == _mX && y == _mY)
- return;
-
- // reset left click MOUSE_VIEW toggle feature
- _mVtoggle = 0;
-
- ww = current_view.get_winWidth();
- wh = current_view.get_winHeight();
-
- switch (mouse_mode) {
- case MOUSE_YOKE:
- if( !mouse_joystick_control ) {
- mouse_joystick_control = 1;
- current_options.set_control_mode( fgOPTIONS::FG_MOUSE );
- } else {
- if ( left_button() ) {
- offset = (_mX - x) * brake_sensitivity;
- controls.move_brake(FGControls::ALL_WHEELS, offset);
- offset = (_mY - y) * throttle_sensitivity;
- controls.move_throttle(FGControls::ALL_ENGINES, offset);
- } else if ( right_button() ) {
- if( ! current_autopilot->get_HeadingEnabled() ) {
- offset = (x - _mX) * rudder_sensitivity;
- controls.move_rudder(offset);
- }
- if( ! current_autopilot->get_AltitudeEnabled() ) {
- offset = (_mY - y) * trim_sensitivity;
- controls.move_elevator_trim(offset);
- }
- } else {
- if( ! current_autopilot->get_HeadingEnabled() ) {
- offset = (x - _mX) * aileron_sensitivity;
- controls.move_aileron(offset);
- }
- if( ! current_autopilot->get_AltitudeEnabled() ) {
- offset = (_mY - y) * elevator_sensitivity;
- controls.move_elevator(offset);
- }
- }
- }
- // Keep the mouse in the window.
- if (x < 5 || x > ww-5 || y < 5 || y > wh-5) {
- x = ww / 2;
- y = wh / 2;
- need_warp = 1;
- }
- break;
-
- case MOUSE_VIEW:
- if( y <= 0 ) {
-#define CONTRAINED_MOUSE_VIEW_Y
-#ifdef CONTRAINED_MOUSE_VIEW_Y
- y = 1;
-#else
- y = wh-2;
-#endif // CONTRAINED_MOUSE_VIEW_Y
- need_warp = 1;
- } else if( y >= wh-1) {
-#ifdef CONTRAINED_MOUSE_VIEW_Y
- y = wh-2;
-#else
- y = 1;
-#endif // CONTRAINED_MOUSE_VIEW_Y
- need_warp = 1;
- }
- // wrap MOUSE_VIEW mode cursor x position
- if ( x <= 0 ) {
- need_warp = 1;
- x = ww-2;
- } else if ( x >= ww-1 ) {
- need_warp = 1;
- x = 1;
- }
- // try to get FG_PI movement in each half of screen
- // do spherical pan
- W = ww;
- H = wh;
- if( middle_button() ) {
- trackball(lastquat,
- (2.0f * _mX - W) / W,
- 0, //(H - 2.0f * y) / H, // 3
- (2.0f * x - W) / W,
- 0 //(H - 2.0f * _mY) / H // 1
- );
- x = _mX;
- y = _mY;
- need_warp = 1;
- } else {
- trackball(lastquat,
- 0, //(2.0f * _mX - W) / W, // 0
- (H - 2.0f * y) / H, // 3
- 0, //(2.0f * x - W) / W, // 2
- (H - 2.0f * _mY) / H // 1
- );
- }
- add_quats(lastquat, curquat, curquat);
- build_rotmatrix(quat_mat, curquat);
-
- // do horizontal pan
- // this could be done in above quat
- // but requires redoing view pipeline
- offset = current_view.get_goal_view_offset();
- offset += ((_mX - x) * FG_2PI / W );
- while (offset < 0.0) {
- offset += FG_2PI;
- }
- while (offset > FG_2PI) {
- offset -= FG_2PI;
- }
- current_view.set_goal_view_offset(offset);
-#ifdef NO_SMOOTH_MOUSE_VIEW
- current_view.set_view_offset(offset);
-#endif
- break;
-
- default:
- break;
- }
- }
- if( need_warp)
- glutWarpPointer(x, y);
-
- // Record the new mouse position.
- _mX = x;
- _mY = y;
-}
-
-
-void guiMouseFunc(int button, int updown, int x, int y)
-{
- int glutModifiers;
-
- // private MOUSE_VIEW state variables
- // to allow alternate left clicks in MOUSE_VIEW mode
- // to toggle between current offsets and straight ahead
- // uses _mVtoggle
- static int _mVx, _mVy, _Vx, _Vy;
- static float _quat[4];
- static double _view_offset;
-
- // general purpose variables
- double offset;
-
- glutModifiers = glutGetModifiers();
- glut_active_shift = glutModifiers & GLUT_ACTIVE_SHIFT;
- glut_active_ctrl = glutModifiers & GLUT_ACTIVE_CTRL;
- glut_active_alt = glutModifiers & GLUT_ACTIVE_ALT;
-
- // Was the left button pressed?
- if (updown == GLUT_DOWN ) {
- if( button == GLUT_LEFT_BUTTON)
- {
- switch (mouse_mode) {
- case MOUSE_POINTER:
- break;
- case MOUSE_YOKE:
- break;
- case MOUSE_VIEW:
- if(_mVtoggle) {
- // resume previous view offsets
- _mX = _mVx;
- _mY = _mVy;
- x = _Vx;
- y = _Vy;
- curquat[0] = _quat[0];
- curquat[1] = _quat[1];
- curquat[2] = _quat[2];
- curquat[3] = _quat[3];
- current_view.set_goal_view_offset(_view_offset);
-#ifdef NO_SMOOTH_MOUSE_VIEW
- current_view.set_view_offset(_view_offset);
-#endif
- } else {
- // center view
- _mVx = _mX;
- _mVy = _mY;
- _Vx = x;
- _Vy = y;
- _quat[0] = curquat[0];
- _quat[1] = curquat[1];
- _quat[2] = curquat[2];
- _quat[3] = curquat[3];
- x = current_view.get_winWidth()/2;
- y = current_view.get_winHeight()/2;
- Quat0();
- _view_offset = current_view.get_goal_view_offset();
- current_view.set_goal_view_offset(0.0);
-#ifdef NO_SMOOTH_MOUSE_VIEW
- current_view.set_view_offset(0.0);
-#endif
- }
- glutWarpPointer( x , y);
- build_rotmatrix(quat_mat, curquat);
- _mVtoggle = ~_mVtoggle;
- break;
- }
- }else if ( button == GLUT_RIGHT_BUTTON) {
- switch (mouse_mode) {
- case MOUSE_POINTER:
- mouse_mode = MOUSE_YOKE;
- mouse_joystick_control = 0;
- _savedX = x;
- _savedY = y;
- // start with zero point in center of screen
- _mX = current_view.get_winWidth()/2;
- _mY = current_view.get_winHeight()/2;
-
- // try to have the MOUSE_YOKE position
- // reflect the current stick position
- offset = controls.get_aileron();
- x = _mX - (int)(offset * aileron_sensitivity);
- offset = controls.get_elevator();
- y = _mY - (int)(offset * elevator_sensitivity);
-
- glutSetCursor(GLUT_CURSOR_CROSSHAIR);
- FG_LOG( FG_INPUT, FG_INFO, "Mouse in yoke mode" );
- break;
-
- case MOUSE_YOKE:
- mouse_mode = MOUSE_VIEW;
- current_options.set_control_mode( fgOPTIONS::FG_JOYSTICK );
- x = current_view.get_winWidth()/2;
- y = current_view.get_winHeight()/2;
- _mVtoggle = 0;
- Quat0();
- build_rotmatrix(quat_mat, curquat);
- glutSetCursor(GLUT_CURSOR_LEFT_RIGHT);
- FG_LOG( FG_INPUT, FG_INFO, "Mouse in view mode" );
- break;
-
- case MOUSE_VIEW:
- mouse_mode = MOUSE_POINTER;
- x = _savedX;
- y = _savedY;
-#ifdef RESET_VIEW_ON_LEAVING_MOUSE_VIEW
- Quat0();
- build_rotmatrix(quat_mat, curquat);
- current_view.set_goal_view_offset(0.0);
-#ifdef NO_SMOOTH_MOUSE_VIEW
- current_view.set_view_offset(0.0);
-#endif
-#endif // RESET_VIEW_ON_LEAVING_MOUSE_VIEW
- glutSetCursor(GLUT_CURSOR_INHERIT);
-
- if(!menu_on)
- TurnCursorOff();
-
- FG_LOG( FG_INPUT, FG_INFO, "Mouse in pointer mode" );
- break;
- }
- glutWarpPointer( x, y );
- } // END RIGHT BUTTON
- } // END UPDOWN == GLUT_DOWN
-
- // Note which button is pressed.
- if ( updown == GLUT_DOWN ) {
- last_buttons |= ( 1 << button ) ;
- } else {
- last_buttons &= ~( 1 << button ) ;
- }
-
- // If we're in pointer mode, let PUI
- // know what's going on.
- if (mouse_mode == MOUSE_POINTER) {
- if (!puMouse (button, updown, x,y)) {
- current_panel->doMouseAction(button, updown, x, y);
- }
- }
-
- // Register the new position (if it
- // hasn't been registered already).
- _mX = x;
- _mY = y;
-
- glutPostRedisplay ();
-}
-
-/* ================ General Purpose Functions ================ */
-
-// Intercept the Escape Key
-void ConfirmExitDialog(void)
-{
- FG_PUSH_PUI_DIALOG( YNdialogBox );
-}
-
-// General Purpose Message Box
-void mkDialog (const char *txt)
-{
- strncpy(global_dialog_string, txt, 256);
- dialogBoxMessage->setLabel(global_dialog_string);
- FG_PUSH_PUI_DIALOG( dialogBox );
-}
-
-// Repair any damage done to the Panel by other Gui Items
-void guiFixPanel( void )
-{
- int toggle_pause;
-
- if ( current_options.get_panel_status() ) {
- FGView *v = ¤t_view;
- FGTime *t = FGTime::cur_time_params;