]> git.mxchange.org Git - flightgear.git/blob - src/GUI/gui.cxx
Updates from David Megginson.
[flightgear.git] / src / GUI / gui.cxx
1 /**************************************************************************
2  * gui.cxx
3  *
4  * Written 1998 by Durk Talsma, started Juni, 1998.  For the flight gear
5  * project.
6  *
7  * Additional mouse supported added by David Megginson, 1999.
8  *
9  * This program is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU General Public License as
11  * published by the Free Software Foundation; either version 2 of the
12  * License, or (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful, but
15  * WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  * General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22  *
23  * $Id$
24  **************************************************************************/
25
26
27 #ifdef HAVE_CONFIG_H
28 #  include <config.h>
29 #endif
30
31 #include <Include/compiler.h>
32
33 #ifdef FG_MATH_EXCEPTION_CLASH
34 #  include <math.h>
35 #endif
36
37 #ifdef HAVE_WINDOWS_H
38 #  include <windows.h>
39 #endif
40
41 #include <GL/glut.h>
42 #include <XGL/xgl.h>
43
44 #if defined(FX) && defined(XMESA)
45 #  include <GL/xmesa.h>
46 #endif
47
48 #include STL_STRING
49
50 #include <stdlib.h>
51 #include <string.h>
52
53 #include <Include/general.hxx>
54 #include <Debug/logstream.hxx>
55 #include <Aircraft/aircraft.hxx>
56 #include <Airports/simple.hxx>
57 #include <Cockpit/panel.hxx>
58 #include <FDM/flight.hxx>
59 #include <Main/options.hxx>
60 #include <Main/fg_init.hxx>
61 #include <Main/views.hxx>
62 #include <Misc/fgpath.hxx>
63 #include <Network/network.h>
64 #include <Time/fg_time.hxx>
65
66 #include "gui.h"
67
68 FG_USING_STD(string);
69
70 #ifndef FG_HAVE_NATIVE_SGI_COMPILERS
71 FG_USING_STD(cout);
72 #endif
73
74 puFont guiFnt = 0;
75 fntTexFont *guiFntHandle = 0;
76
77 static puMenuBar    *mainMenuBar = 0;
78 //static puButton     *hideMenuButton = 0;
79
80 static puDialogBox  *dialogBox = 0;
81 static puFrame      *dialogFrame = 0;
82 static puText       *dialogBoxMessage = 0;
83 static puOneShot    *dialogBoxOkButton = 0;
84
85
86 static puDialogBox  *YNdialogBox = 0;
87 static puFrame      *YNdialogFrame = 0;
88 static puText       *YNdialogBoxMessage = 0;
89 static puOneShot    *YNdialogBoxOkButton = 0;
90 static puOneShot    *YNdialogBoxNoButton = 0;
91
92 static char msg_OK[]     = "OK";
93 static char msg_NO[]     = "NO";
94 static char msg_YES[]    = "YES";
95 static char msg_CANCEL[] = "Cancel";
96 static char msg_RESET[]  = "Reset";
97
98 char *gui_msg_OK;     // "OK"
99 char *gui_msg_NO;     // "NO"
100 char *gui_msg_YES;    // "YES"
101 char *gui_msg_CANCEL; // "CANCEL"
102 char *gui_msg_RESET;  // "RESET"
103
104 static char global_dialog_string[256];
105
106 extern void NewAltitude( puObject *cb );
107 extern void NewHeading( puObject *cb );
108 extern void fgAPAdjust( puObject * );
109 extern void fgLatLonFormatToggle( puObject *);
110
111 /* --------------------------------------------------------------------
112 Mouse stuff
113 ---------------------------------------------------------------------*/
114
115 static int _mX = 0;
116 static int _mY = 0;
117 static int _savedX = 0;
118 static int _savedY = 0;
119 static int last_buttons = 0 ;
120 static int mouse_active = 0;
121 static int menu_on = 0;
122
123 /* --------------------------------------------------------------------
124 Support for mouse as control yoke (david@megginson.com)
125
126 - right button toggles between pointer and yoke
127 - horizontal drag with no buttons moves ailerons
128 - vertical drag with no buttons moves elevators
129 - horizontal drag with left button moves brakes (left=on)
130 - vertical drag with left button moves throttle (up=more)
131 - horizontal drag with middle button moves rudder
132 - vertical drag with middle button moves trim
133
134 For the *_sensitivity variables, a lower number means more sensitive.
135
136 TODO: figure out how to keep pointer from leaving window in yoke mode.
137 TODO: add thresholds and null zones
138 TODO: sensitivity should be configurable at user option.
139 TODO: allow differential braking (this will be useful if FlightGear
140       ever supports tail-draggers like the DC-3)
141 ---------------------------------------------------------------------*/
142
143 static int mouse_yoke = 0;
144 static float aileron_sensitivity = 500.0;
145 static float elevator_sensitivity = 500.0;
146 static float brake_sensitivity = 250.0;
147 static float throttle_sensitivity = 250.0;
148 static float rudder_sensitivity = 500.0;
149 static float trim_sensitivity = 1000.0;
150
151 void guiMotionFunc ( int x, int y )
152 {
153     if (mouse_yoke) {
154         int ww = current_view.get_winWidth();
155         int wh = current_view.get_winHeight();
156
157         if (last_buttons & (1 << GLUT_LEFT_BUTTON)) {
158             float brake_offset = (_mX - x) / brake_sensitivity;
159             float throttle_offset = (_mY - y) / throttle_sensitivity;
160             controls.move_brake(FGControls::ALL_WHEELS, brake_offset);
161             controls.move_throttle(FGControls::ALL_ENGINES, throttle_offset);
162         } else if (last_buttons & (1 << GLUT_MIDDLE_BUTTON)) {
163             float rudder_offset = (x - _mX) / rudder_sensitivity;
164             float trim_offset = (_mY - y) / trim_sensitivity;
165             controls.move_rudder(rudder_offset);
166             controls.move_elevator_trim(trim_offset);
167         } else {
168             float aileron_offset = (x - _mX) / aileron_sensitivity;
169             float elevator_offset = (_mY - y) / elevator_sensitivity;
170             controls.move_aileron(aileron_offset);
171             controls.move_elevator(elevator_offset);
172         }
173         if (x < 5 || x > ww-5 || y < 5 || y > wh-5) {
174             _mX = x = ww / 2;
175             _mY = y = wh / 2;
176             glutWarpPointer(x, y);
177         }
178     } else {
179         puMouse ( x, y ) ;
180         glutPostRedisplay () ;
181     }
182     _mX = x;
183     _mY = y;
184 }
185
186 void guiMouseFunc(int button, int updown, int x, int y)
187 {
188     // Toggle mouse as pointer or yoke
189     if (updown == GLUT_DOWN && (button & GLUT_RIGHT_BUTTON)) {
190         FG_LOG( FG_INPUT, FG_INFO, "Toggling mouse as yoke" );
191         mouse_yoke = !mouse_yoke;
192         if (mouse_yoke) {
193             FG_LOG( FG_INPUT, FG_INFO, "Mouse in yoke mode" );
194             _savedX = x;
195             _savedY = y;
196             glutSetCursor(GLUT_CURSOR_NONE);
197         } else {
198             _mX = x = _savedX;
199             _mY = y = _savedY;
200             glutWarpPointer(x, y);
201             glutSetCursor(GLUT_CURSOR_INHERIT);
202             FG_LOG( FG_INPUT, FG_INFO, "Mouse in pointer mode" );
203         }
204     }
205     _mX = x;
206     _mY = y;
207     if ( updown == PU_DOWN ) {
208         last_buttons |=  ( 1 << button ) ;
209     } else {
210         last_buttons &= ~( 1 << button ) ;
211     }
212     if (!mouse_yoke) {
213         puMouse (button, updown, x,y);
214         glutPostRedisplay ();
215     }
216 }
217
218 int guiGetMouseButton(void)
219 {
220     return last_buttons;
221 }
222
223 void guiGetMouse(int *x, int *y)
224 {
225     *x = _mX;
226     *y = _mY;
227 };
228
229 static inline void TurnCursorOn( void )
230 {
231     mouse_active = ~0;
232 #if defined ( WIN32 ) || defined(__CYGWIN32__)
233     glutSetCursor(GLUT_CURSOR_INHERIT);
234 #endif
235 #if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 9)
236     glutWarpPointer( glutGet(GLUT_SCREEN_WIDTH)/2, glutGet(GLUT_SCREEN_HEIGHT)/2);
237 #endif
238 }
239
240 static inline void TurnCursorOff( void )
241 {
242     mouse_active = 0;
243 #if defined ( WIN32 ) || defined(__CYGWIN32__)
244     glutSetCursor(GLUT_CURSOR_NONE);
245 #else  // I guess this is what we want to do ??
246 #if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 9)
247     glutWarpPointer( glutGet(GLUT_SCREEN_WIDTH), glutGet(GLUT_SCREEN_HEIGHT));
248 #endif
249 #endif
250 }
251
252 void maybeToggleMouse( void )
253 {
254 #ifdef WIN32
255     static int first_time = ~0;
256     static int mouse_changed = 0;
257
258     if ( first_time ) {
259         if(!mouse_active) {
260             mouse_changed = ~mouse_changed;
261             TurnCursorOn();
262         }
263     } else {
264         if( mouse_changed ) {
265             mouse_changed = ~mouse_changed;
266             if(mouse_active) {
267                 TurnCursorOff();
268             }
269         }
270     }
271     first_time = ~first_time;
272 #endif // #ifdef WIN32
273 }
274
275 // Call with FALSE to init and TRUE to restore
276 void BusyCursor( int restore )
277 {
278     static int cursor = 0;
279     if( restore ) {
280         glutSetCursor(cursor);
281     } else {
282         cursor = glutGet( GLUT_WINDOW_CURSOR );
283 #ifdef WIN32
284         TurnCursorOn();
285 #endif
286         glutSetCursor( GLUT_CURSOR_WAIT );
287     }
288 }
289 /* ================ General Purpose Functions ================ */
290
291 // Intercept the Escape Key
292 void ConfirmExitDialog(void)
293 {
294     FG_PUSH_PUI_DIALOG( YNdialogBox );
295 }
296
297 // General Purpose Message Box
298 void mkDialog (const char *txt)
299 {
300     strncpy(global_dialog_string, txt, 256);
301     dialogBoxMessage->setLabel(global_dialog_string);
302     FG_PUSH_PUI_DIALOG( dialogBox );
303 }
304
305 // Repair any damage done to the Panel by other Gui Items
306 void guiFixPanel( void )
307 {
308     int toggle_pause;
309
310     if ( current_options.get_panel_status() ) {
311         FGView *v = &current_view;
312         FGTime *t = FGTime::cur_time_params;
313
314         if( (toggle_pause = !t->getPause()) )
315             t->togglePauseMode();
316
317         // this seems to be the only way to do this :-(
318         // problem is the viewport has been mucked with
319         xglViewport(0, 0 , (GLint)(v->winWidth), (GLint)(v->winHeight) );
320         FGPanel::OurPanel->ReInit(0, 0, 1024, 768);
321
322         if(toggle_pause)
323             t->togglePauseMode();
324     }
325 }
326
327 // Toggle the Menu and Mouse display state
328 void guiToggleMenu(void)
329 {
330     if( menu_on ) {
331         // printf("Hiding Menu\n");
332         mainMenuBar->hide  ();
333 #ifdef WIN32
334         TurnCursorOff();
335 #endif // #ifdef WIN32
336     } else {
337         // printf("Showing Menu\n");
338         mainMenuBar->reveal();
339 #ifdef WIN32
340         TurnCursorOn();
341 #endif // #ifdef WIN32
342     }
343     menu_on = ~menu_on;
344 }
345     
346 /* -----------------------------------------------------------------------
347 the Gui callback functions 
348 ____________________________________________________________________*/
349
350 void reInit(puObject *cb)
351 {
352     BusyCursor(0);
353     fgReInitSubsystems();
354     BusyCursor(1);
355 }
356         
357 // This is the accessor function
358 void guiTogglePanel(puObject *cb)
359 {
360     current_options.toggle_panel();
361 }
362     
363 //void MenuHideMenuCb(puObject *cb)
364 void hideMenuCb (puObject *cb)
365 {
366     guiToggleMenu();
367 }
368
369 void goodBye(puObject *)
370 {
371     // FG_LOG( FG_INPUT, FG_ALERT,
372     //      "Program exiting normally at user request." );
373     cout << "Program exiting normally at user request." << endl;
374
375     //  if(gps_bug)
376     //      fclose(gps_bug);
377
378     exit(-1);
379 }
380
381
382 void goAwayCb (puObject *me)
383 {
384     FG_POP_PUI_DIALOG( dialogBox );
385 }
386
387 void mkDialogInit (void)
388 {
389     //  printf("mkDialogInit\n");
390     int x = (current_options.get_xsize()/2 - 400/2);
391     int y = (current_options.get_ysize()/2 - 100/2);
392     dialogBox = new puDialogBox (x, y); // 150, 50
393     {
394         dialogFrame = new puFrame (0,0,400,100);
395         dialogBoxMessage  =  new puText         (10, 70);
396         dialogBoxMessage  -> setLabel           ("");
397         dialogBoxOkButton =  new puOneShot      (180, 10, 240, 50);
398         dialogBoxOkButton -> setLegend          (gui_msg_OK);
399         dialogBoxOkButton -> makeReturnDefault  (TRUE );
400         dialogBoxOkButton -> setCallback        (goAwayCb);
401     }
402     FG_FINALIZE_PUI_DIALOG( dialogBox );
403 }
404
405 void MayBeGoodBye(puObject *)
406 {
407     ConfirmExitDialog(); 
408 }
409
410 void goAwayYesNoCb(puObject *me)
411 {
412     FG_POP_PUI_DIALOG( YNdialogBox);
413 }
414
415 void ConfirmExitDialogInit(void)
416 {
417     char msg[] = "Really Quit";
418     char *s;
419
420     //  printf("ConfirmExitDialogInit\n");
421     int len = 200 - puGetStringWidth( puGetDefaultLabelFont(), msg )/2;
422
423     int x = (current_options.get_xsize()/2 - 400/2);
424     int y = (current_options.get_ysize()/2 - 100/2);
425         
426     YNdialogBox = new puDialogBox (x, y); // 150, 50
427     //  YNdialogBox = new puDialogBox (150, 50);
428     {
429         YNdialogFrame = new puFrame (0,0,400, 100);
430         
431         YNdialogBoxMessage  =  new puText         (len, 70);
432         YNdialogBoxMessage  -> setDefaultValue    (msg);
433         YNdialogBoxMessage  -> getDefaultValue    (&s);
434         YNdialogBoxMessage  -> setLabel           (s);
435         
436         YNdialogBoxOkButton =  new puOneShot      (100, 10, 160, 50);
437         YNdialogBoxOkButton -> setLegend          (gui_msg_OK);
438         YNdialogBoxOkButton -> setCallback        (goodBye);
439         
440         YNdialogBoxNoButton =  new puOneShot      (240, 10, 300, 50);
441         YNdialogBoxNoButton -> setLegend          (gui_msg_NO);
442         //      YNdialogBoxNoButton -> makeReturnDefault  (TRUE );
443         YNdialogBoxNoButton -> setCallback        (goAwayYesNoCb);
444     }
445     FG_FINALIZE_PUI_DIALOG( YNdialogBox );
446 }
447
448 void notCb (puObject *)
449 {
450     mkDialog ("This function isn't implemented yet");
451 }
452
453 void helpCb (puObject *)
454 {
455     string command;
456         
457 #if defined(FX) && !defined(WIN32)
458 #  if defined(XMESA_FX_FULLSCREEN) && defined(XMESA_FX_WINDOW)
459     if ( global_fullscreen ) {
460         global_fullscreen = false;
461         XMesaSetFXmode( XMESA_FX_WINDOW );
462     }
463 #  endif
464 #endif
465         
466 #if !defined(WIN32)
467     string url = "http://www.flightgear.org/Docs/InstallGuide/getstart.html";
468         
469     if ( system("xwininfo -name Netscape > /dev/null 2>&1") == 0 ) {
470         command = "netscape -remote \"openURL(" + url + ")\" &";
471     } else {
472         command = "netscape " + url + " &";
473     }
474 #else
475     command = "webrun.bat";
476 #endif
477         
478     system( command.c_str() );
479     //string text = "Help started in netscape window.";
480
481     //mkDialog (text.c_str());
482     mkDialog ("Help started in netscape window.");
483 }
484
485 /// The beginnings of teleportation :-)
486 //  Needs cleaning up but works
487 //  These statics should disapear when this is a class
488 static puDialogBox     *AptDialog = 0;
489 static puFrame         *AptDialogFrame = 0;
490 static puText          *AptDialogMessage = 0;
491 static puInput         *AptDialogInput = 0;
492
493 static char NewAirportId[16];
494 static char NewAirportLabel[] = "Enter New Airport ID"; 
495
496 static puOneShot       *AptDialogOkButton = 0;
497 static puOneShot       *AptDialogCancelButton = 0;
498 static puOneShot       *AptDialogResetButton = 0;
499
500 void AptDialog_Cancel(puObject *)
501 {
502     FG_POP_PUI_DIALOG( AptDialog );
503 }
504
505 void AptDialog_OK (puObject *)
506 {
507         fgAIRPORTS airports;
508         fgAIRPORT a;
509     
510     FGTime *t = FGTime::cur_time_params;
511     int PauseMode = t->getPause();
512     if(!PauseMode)
513         t->togglePauseMode();
514
515     char *s;
516     AptDialogInput->getValue(&s);
517     string AptId(s);
518
519         cout << "AptDialog_OK " << AptId << " " << AptId.length() << endl;
520     
521     AptDialog_Cancel( NULL );
522     
523     if ( AptId.length() ) {
524         // set initial position from airport id
525         FG_LOG( FG_GENERAL, FG_INFO,
526                 "Attempting to set starting position from airport code "
527                 << AptId );
528
529         airports.load("apt_simple");
530         if ( airports.search( AptId, &a ) )
531         {
532             current_options.set_airport_id( AptId.c_str() );
533             BusyCursor(0);
534             fgReInitSubsystems();
535             BusyCursor(1);
536         } else {
537             AptId  += " not in database.";
538             mkDialog(AptId.c_str());
539         }
540     }
541     if( PauseMode != t->getPause() )
542         t->togglePauseMode();
543 }
544
545 void AptDialog_Reset(puObject *)
546 {
547     //  strncpy( NewAirportId, current_options.get_airport_id().c_str(), 16 );
548     sprintf( NewAirportId, "%s", current_options.get_airport_id().c_str() );
549     AptDialogInput->setValue ( NewAirportId );
550     AptDialogInput->setCursor( 0 ) ;
551 }
552
553 void NewAirport(puObject *cb)
554 {
555     //  strncpy( NewAirportId, current_options.get_airport_id().c_str(), 16 );
556     sprintf( NewAirportId, "%s", current_options.get_airport_id().c_str() );
557 //      cout << "NewAirport " << NewAirportId << endl;
558     AptDialogInput->setValue( NewAirportId );
559
560     FG_PUSH_PUI_DIALOG( AptDialog );
561 }
562
563 static void NewAirportInit(void)
564 {
565     sprintf( NewAirportId, "%s", current_options.get_airport_id().c_str() );
566     int len = 150 - puGetStringWidth( puGetDefaultLabelFont(),
567                                       NewAirportLabel ) / 2;
568
569     AptDialog = new puDialogBox (150, 50);
570     {
571         AptDialogFrame   = new puFrame           (0,0,350, 150);
572         AptDialogMessage = new puText            (len, 110);
573         AptDialogMessage ->    setLabel          (NewAirportLabel);
574
575         AptDialogInput   = new puInput           (50, 70, 300, 100);
576         AptDialogInput   ->    setValue          (NewAirportId);
577         AptDialogInput   ->    acceptInput();
578
579         AptDialogOkButton     =  new puOneShot   (50, 10, 110, 50);
580         AptDialogOkButton     ->     setLegend   (gui_msg_OK);
581         AptDialogOkButton     ->     setCallback (AptDialog_OK);
582         AptDialogOkButton     ->     makeReturnDefault(TRUE);
583
584         AptDialogCancelButton =  new puOneShot   (140, 10, 210, 50);
585         AptDialogCancelButton ->     setLegend   (gui_msg_CANCEL);
586         AptDialogCancelButton ->     setCallback (AptDialog_Cancel);
587
588         AptDialogResetButton  =  new puOneShot   (240, 10, 300, 50);
589         AptDialogResetButton  ->     setLegend   (gui_msg_RESET);
590         AptDialogResetButton  ->     setCallback (AptDialog_Reset);
591     }
592         cout << "NewAirportInit " << NewAirportId << endl;
593     FG_FINALIZE_PUI_DIALOG( AptDialog );
594 }
595
596 /// The beginnings of networking :-)
597 //  Needs cleaning up but works
598 //  These statics should disapear when this is a class
599 static puDialogBox     *NetIdDialog = 0;
600 static puFrame         *NetIdDialogFrame = 0;
601 static puText          *NetIdDialogMessage = 0;
602 static puInput         *NetIdDialogInput = 0;
603
604 static char NewNetId[16];
605 static char NewNetIdLabel[] = "Enter New Callsign"; 
606
607 static puOneShot       *NetIdDialogOkButton = 0;
608 static puOneShot       *NetIdDialogCancelButton = 0;
609
610 void NetIdDialog_Cancel(puObject *)
611 {
612     FG_POP_PUI_DIALOG( NetIdDialog );
613 }
614
615 void NetIdDialog_OK (puObject *)
616 {
617     string NetId;
618     
619     FGTime *t = FGTime::cur_time_params;
620     int PauseMode = t->getPause();
621     if(!PauseMode)
622         t->togglePauseMode();
623 /*  
624    The following needs some cleanup because 
625    "string options.NetId" and "char *net_callsign" 
626 */
627     NetIdDialogInput->getValue(&net_callsign);
628     NetId = net_callsign;
629     
630     NetIdDialog_Cancel( NULL );
631     current_options.set_net_id( NetId.c_str() );
632 /* Entering a callsign indicates : user wants Net HUD Info */
633     net_hud_display = 1;
634
635     if( PauseMode != t->getPause() )
636         t->togglePauseMode();
637 }
638
639 void NewCallSign(puObject *cb)
640 {
641     sprintf( NewNetId, "%s", current_options.get_net_id().c_str() );
642     NetIdDialogInput->setValue( NewNetId );
643
644     FG_PUSH_PUI_DIALOG( NetIdDialog );
645 }
646
647 static void NewNetIdInit(void)
648 {
649     sprintf( NewNetId, "%s", current_options.get_net_id().c_str() );
650     int len = 150 - puGetStringWidth( puGetDefaultLabelFont(),
651                                       NewNetIdLabel ) / 2;
652
653     NetIdDialog = new puDialogBox (150, 50);
654     {
655         NetIdDialogFrame   = new puFrame           (0,0,350, 150);
656         NetIdDialogMessage = new puText            (len, 110);
657         NetIdDialogMessage ->    setLabel          (NewNetIdLabel);
658
659         NetIdDialogInput   = new puInput           (50, 70, 300, 100);
660         NetIdDialogInput   ->    setValue          (NewNetId);
661         NetIdDialogInput   ->    acceptInput();
662
663         NetIdDialogOkButton     =  new puOneShot   (50, 10, 110, 50);
664         NetIdDialogOkButton     ->     setLegend   (gui_msg_OK);
665         NetIdDialogOkButton     ->     setCallback (NetIdDialog_OK);
666         NetIdDialogOkButton     ->     makeReturnDefault(TRUE);
667
668         NetIdDialogCancelButton =  new puOneShot   (240, 10, 300, 50);
669         NetIdDialogCancelButton ->     setLegend   (gui_msg_CANCEL);
670         NetIdDialogCancelButton ->     setCallback (NetIdDialog_Cancel);
671
672     }
673     FG_FINALIZE_PUI_DIALOG( NetIdDialog );
674 }
675
676 static void net_display_toggle( puObject *cb)
677 {
678         net_hud_display = (net_hud_display) ? 0 : 1;
679         printf("Toggle net_hud_display : %d\n", net_hud_display);
680 }
681
682 static void net_blaster_toggle( puObject *cb)
683 {
684         net_blast_toggle = (net_blast_toggle) ? 0 : -1;
685         printf("Toggle net_blast : %d\n", net_blast_toggle);
686 }
687
688 /***************  End Networking  **************/
689
690
691
692 /* -----------------------------------------------------------------------
693 The menu stuff 
694 ---------------------------------------------------------------------*/
695 char *fileSubmenu               [] = {
696     "Exit", "Close", "---------", "Print", "---------", "Save", "Reset", NULL
697 };
698 puCallback fileSubmenuCb        [] = {
699     MayBeGoodBye, hideMenuCb, NULL, notCb, NULL, notCb, reInit, NULL
700 };
701
702 char *editSubmenu               [] = {
703     "Edit text", NULL
704 };
705 puCallback editSubmenuCb        [] = {
706     notCb, NULL
707 };
708
709 char *viewSubmenu               [] = {
710     "Cockpit View > ", "View >","------------", "Toggle Panel...", NULL
711 };
712 puCallback viewSubmenuCb        [] = {
713     notCb, notCb, NULL, guiTogglePanel, NULL
714 };
715
716 char *aircraftSubmenu           [] = {
717     "Autopilot", "Heading", "Altitude", "Navigation", "Communication", NULL
718 };
719 puCallback aircraftSubmenuCb    [] = {
720     fgAPAdjust, NewHeading, NewAltitude, fgLatLonFormatToggle, notCb, NULL
721 };
722
723 char *environmentSubmenu        [] = {
724     "Airport", "Terrain", "Weather", NULL
725 };
726 puCallback environmentSubmenuCb [] = {
727     NewAirport, notCb, notCb, NULL
728 };
729
730 char *optionsSubmenu            [] = {
731     "Preferences", "Realism & Reliablity...", NULL
732 };
733 puCallback optionsSubmenuCb     [] = {
734     notCb, notCb, NULL
735 };
736
737 #ifdef FG_NETWORK_OLK
738 char *networkSubmenu            [] = {
739     "Unregister from FGD ", "Send MSG to All", "Send MSG", "Show Pilots", "Register to FGD",
740     "Scan for Deamons", "Enter Callsign", "Display Netinfos", "Toggle Display",
741     "Hyper Blast", NULL
742 };
743 puCallback networkSubmenuCb     [] = {
744     notCb, notCb, notCb, notCb, notCb, notCb, NewCallSign, notCb,
745     net_display_toggle, net_blaster_toggle, NULL
746 };
747 #endif
748
749 char *helpSubmenu               [] = {
750     "About...", "Help", NULL
751 };
752 puCallback helpSubmenuCb        [] = {
753     notCb, helpCb, NULL
754 };
755
756
757 /* -------------------------------------------------------------------------
758 init the gui
759 _____________________________________________________________________*/
760
761
762 void guiInit()
763 {
764     char *mesa_win_state;
765
766     // Initialize PUI
767     puInit();
768     puSetDefaultStyle         ( PUSTYLE_SMALL_BEVELLED ); //PUSTYLE_DEFAULT
769     puSetDefaultColourScheme  (0.8, 0.8, 0.8, 0.4);
770
771     // Initialize our GLOBAL GUI STRINGS
772     gui_msg_OK     = msg_OK;     // "OK"
773     gui_msg_NO     = msg_NO;     // "NO"
774     gui_msg_YES    = msg_YES;    // "YES"
775     gui_msg_CANCEL = msg_CANCEL; // "CANCEL"
776     gui_msg_RESET  = msg_RESET;  // "RESET"
777
778     // Next check home directory
779     FGPath fntpath;
780     char* envp = ::getenv( "FG_FONTS" );
781     if ( envp != NULL ) {
782         fntpath.set( envp );
783     } else {
784         fntpath.set( current_options.get_fg_root() );
785         fntpath.append( "Fonts" );
786     }
787
788     // Install our fast fonts
789     fntpath.append( "typewriter.txf" );
790     guiFntHandle = new fntTexFont ;
791     guiFntHandle -> load ( (char *)fntpath.c_str() ) ;
792     puFont GuiFont ( guiFntHandle, 15 ) ;
793     puSetDefaultFonts( GuiFont, GuiFont ) ;
794     guiFnt = puGetDefaultLabelFont();
795   
796     if ( current_options.get_mouse_pointer() == 0 ) {
797         // no preference specified for mouse pointer, attempt to autodetect...
798         // Determine if we need to render the cursor, or if the windowing
799         // system will do it.  First test if we are rendering with glide.
800         if ( strstr ( general.get_glRenderer(), "Glide" ) ) {
801             // Test for the MESA_GLX_FX env variable
802             if ( (mesa_win_state = getenv( "MESA_GLX_FX" )) != NULL) {
803                 // test if we are fullscreen mesa/glide
804                 if ( (mesa_win_state[0] == 'f') ||
805                      (mesa_win_state[0] == 'F') ) {
806                     puShowCursor ();
807                 }
808             }
809         }
810         mouse_active = ~mouse_active;
811     } else if ( current_options.get_mouse_pointer() == 1 ) {
812         // don't show pointer
813     } else if ( current_options.get_mouse_pointer() == 2 ) {
814         // force showing pointer
815         puShowCursor();
816         mouse_active = ~mouse_active;
817     }
818
819     // Set up our Dialog Boxes
820     ConfirmExitDialogInit();
821     NewAirportInit();
822 #ifdef FG_NETWORK_OLK
823     NewNetIdInit();
824 #endif
825     mkDialogInit();
826     
827     // Make the menu bar
828     mainMenuBar = new puMenuBar ();
829     mainMenuBar -> add_submenu ("File", fileSubmenu, fileSubmenuCb);
830     mainMenuBar -> add_submenu ("Edit", editSubmenu, editSubmenuCb);
831     mainMenuBar -> add_submenu ("View", viewSubmenu, viewSubmenuCb);
832     mainMenuBar -> add_submenu ("Aircraft", aircraftSubmenu, aircraftSubmenuCb);
833     mainMenuBar -> add_submenu ("Environment", environmentSubmenu, environmentSubmenuCb);
834     mainMenuBar -> add_submenu ("Options", optionsSubmenu, optionsSubmenuCb);
835 #ifdef FG_NETWORK_OLK
836     mainMenuBar -> add_submenu ("Network", networkSubmenu, networkSubmenuCb);
837 #endif
838     mainMenuBar -> add_submenu ("Help", helpSubmenu, helpSubmenuCb);
839     mainMenuBar-> close ();
840     // Set up menu bar toggle
841     menu_on = ~0;
842 }