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