]> git.mxchange.org Git - flightgear.git/blob - src/GUI/gui.cxx
Updated to support new weather subsystem (visibility variable determins
[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     string AptId;
492     
493     FGTime *t = FGTime::cur_time_params;
494     int PauseMode = t->getPause();
495     if(!PauseMode)
496         t->togglePauseMode();
497
498     char *s;
499     AptDialogInput->getValue(&s);
500     AptId = s;
501     
502     AptDialog_Cancel( NULL );
503     
504     if ( AptId.length() ) {
505         // set initial position from airport id
506         fgAIRPORTS airports;
507         fgAIRPORT a;
508
509         FG_LOG( FG_GENERAL, FG_INFO,
510                 "Attempting to set starting position from airport code "
511                 << s );
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     AptDialogInput->setValue( NewAirportId );
542
543     FG_PUSH_PUI_DIALOG( AptDialog );
544 }
545
546 static void NewAirportInit(void)
547 {
548     sprintf( NewAirportId, "%s", current_options.get_airport_id().c_str() );
549     int len = 150 - puGetStringWidth( puGetDefaultLabelFont(),
550                                       NewAirportLabel ) / 2;
551
552     AptDialog = new puDialogBox (150, 50);
553     {
554         AptDialogFrame   = new puFrame           (0,0,350, 150);
555         AptDialogMessage = new puText            (len, 110);
556         AptDialogMessage ->    setLabel          (NewAirportLabel);
557
558         AptDialogInput   = new puInput           (50, 70, 300, 100);
559         AptDialogInput   ->    setValue          (NewAirportId);
560         AptDialogInput   ->    acceptInput();
561
562         AptDialogOkButton     =  new puOneShot   (50, 10, 110, 50);
563         AptDialogOkButton     ->     setLegend   (gui_msg_OK);
564         AptDialogOkButton     ->     setCallback (AptDialog_OK);
565         AptDialogOkButton     ->     makeReturnDefault(TRUE);
566
567         AptDialogCancelButton =  new puOneShot   (140, 10, 210, 50);
568         AptDialogCancelButton ->     setLegend   (gui_msg_CANCEL);
569         AptDialogCancelButton ->     setCallback (AptDialog_Cancel);
570
571         AptDialogResetButton  =  new puOneShot   (240, 10, 300, 50);
572         AptDialogResetButton  ->     setLegend   (gui_msg_RESET);
573         AptDialogResetButton  ->     setCallback (AptDialog_Reset);
574     }
575     FG_FINALIZE_PUI_DIALOG( AptDialog );
576 }
577
578 /// The beginnings of networking :-)
579 //  Needs cleaning up but works
580 //  These statics should disapear when this is a class
581 static puDialogBox     *NetIdDialog = 0;
582 static puFrame         *NetIdDialogFrame = 0;
583 static puText          *NetIdDialogMessage = 0;
584 static puInput         *NetIdDialogInput = 0;
585
586 static char NewNetId[16];
587 static char NewNetIdLabel[] = "Enter New Callsign"; 
588
589 static puOneShot       *NetIdDialogOkButton = 0;
590 static puOneShot       *NetIdDialogCancelButton = 0;
591
592 void NetIdDialog_Cancel(puObject *)
593 {
594     FG_POP_PUI_DIALOG( NetIdDialog );
595 }
596
597 void NetIdDialog_OK (puObject *)
598 {
599     string NetId;
600     
601     FGTime *t = FGTime::cur_time_params;
602     int PauseMode = t->getPause();
603     if(!PauseMode)
604         t->togglePauseMode();
605 /*  
606    The following needs some cleanup because 
607    "string options.NetId" and "char *net_callsign" 
608 */
609     NetIdDialogInput->getValue(&net_callsign);
610     NetId = net_callsign;
611     
612     NetIdDialog_Cancel( NULL );
613     current_options.set_net_id( NetId.c_str() );
614 /* Entering a callsign indicates : user wants Net HUD Info */
615     net_hud_display = 1;
616
617     if( PauseMode != t->getPause() )
618         t->togglePauseMode();
619 }
620
621 void NewCallSign(puObject *cb)
622 {
623     sprintf( NewNetId, "%s", current_options.get_net_id().c_str() );
624     NetIdDialogInput->setValue( NewNetId );
625
626     FG_PUSH_PUI_DIALOG( NetIdDialog );
627 }
628
629 static void NewNetIdInit(void)
630 {
631     sprintf( NewNetId, "%s", current_options.get_net_id().c_str() );
632     int len = 150 - puGetStringWidth( puGetDefaultLabelFont(),
633                                       NewNetIdLabel ) / 2;
634
635     NetIdDialog = new puDialogBox (150, 50);
636     {
637         NetIdDialogFrame   = new puFrame           (0,0,350, 150);
638         NetIdDialogMessage = new puText            (len, 110);
639         NetIdDialogMessage ->    setLabel          (NewNetIdLabel);
640
641         NetIdDialogInput   = new puInput           (50, 70, 300, 100);
642         NetIdDialogInput   ->    setValue          (NewNetId);
643         NetIdDialogInput   ->    acceptInput();
644
645         NetIdDialogOkButton     =  new puOneShot   (50, 10, 110, 50);
646         NetIdDialogOkButton     ->     setLegend   (gui_msg_OK);
647         NetIdDialogOkButton     ->     setCallback (NetIdDialog_OK);
648         NetIdDialogOkButton     ->     makeReturnDefault(TRUE);
649
650         NetIdDialogCancelButton =  new puOneShot   (240, 10, 300, 50);
651         NetIdDialogCancelButton ->     setLegend   (gui_msg_CANCEL);
652         NetIdDialogCancelButton ->     setCallback (NetIdDialog_Cancel);
653
654     }
655     FG_FINALIZE_PUI_DIALOG( NetIdDialog );
656 }
657
658 static void net_display_toggle( puObject *cb)
659 {
660         net_hud_display = (net_hud_display) ? 0 : 1;
661         printf("Toggle net_hud_display : %d\n", net_hud_display);
662 }
663
664 static void net_blaster_toggle( puObject *cb)
665 {
666         net_blast_toggle = (net_blast_toggle) ? 0 : -1;
667         printf("Toggle net_blast : %d\n", net_blast_toggle);
668 }
669
670 /***************  End Networking  **************/
671
672
673
674 /* -----------------------------------------------------------------------
675 The menu stuff 
676 ---------------------------------------------------------------------*/
677 char *fileSubmenu               [] = {
678     "Exit", "Close", "---------", "Print", "---------", "Save", "Reset", NULL
679 };
680 puCallback fileSubmenuCb        [] = {
681     MayBeGoodBye, hideMenuCb, NULL, notCb, NULL, notCb, reInit, NULL
682 };
683
684 char *editSubmenu               [] = {
685     "Edit text", NULL
686 };
687 puCallback editSubmenuCb        [] = {
688     notCb, NULL
689 };
690
691 char *viewSubmenu               [] = {
692     "Cockpit View > ", "View >","------------", "Toggle Panel...", NULL
693 };
694 puCallback viewSubmenuCb        [] = {
695     notCb, notCb, NULL, guiTogglePanel, NULL
696 };
697
698 char *aircraftSubmenu           [] = {
699     "Autopilot", "Heading", "Altitude", "Navigation", "Communication", NULL
700 };
701 puCallback aircraftSubmenuCb    [] = {
702     fgAPAdjust, NewHeading, NewAltitude, fgLatLonFormatToggle, notCb, NULL
703 };
704
705 char *environmentSubmenu        [] = {
706     "Airport", "Terrain", "Weather", NULL
707 };
708 puCallback environmentSubmenuCb [] = {
709     NewAirport, notCb, notCb, NULL
710 };
711
712 char *optionsSubmenu            [] = {
713     "Preferences", "Realism & Reliablity...", NULL
714 };
715 puCallback optionsSubmenuCb     [] = {
716     notCb, notCb, NULL
717 };
718
719 #ifdef FG_NETWORK_OLK
720 char *networkSubmenu            [] = {
721     "Unregister from FGD ", "Send MSG to All", "Send MSG", "Show Pilots", "Register to FGD",
722     "Scan for Deamons", "Enter Callsign", "Display Netinfos", "Toggle Display",
723     "Hyper Blast", NULL
724 };
725 puCallback networkSubmenuCb     [] = {
726     notCb, notCb, notCb, notCb, notCb, notCb, NewCallSign, notCb,
727     net_display_toggle, net_blaster_toggle, NULL
728 };
729 #endif
730
731 char *helpSubmenu               [] = {
732     "About...", "Help", NULL
733 };
734 puCallback helpSubmenuCb        [] = {
735     notCb, helpCb, NULL
736 };
737
738
739 /* -------------------------------------------------------------------------
740 init the gui
741 _____________________________________________________________________*/
742
743
744 void guiInit()
745 {
746     char *mesa_win_state;
747
748     // Initialize PUI
749     puInit();
750     puSetDefaultStyle         ( PUSTYLE_SMALL_BEVELLED ); //PUSTYLE_DEFAULT
751     puSetDefaultColourScheme  (0.8, 0.8, 0.8, 0.4);
752
753     // Initialize our GLOBAL GUI STRINGS
754     gui_msg_OK     = msg_OK;     // "OK"
755     gui_msg_NO     = msg_NO;     // "NO"
756     gui_msg_YES    = msg_YES;    // "YES"
757     gui_msg_CANCEL = msg_CANCEL; // "CANCEL"
758     gui_msg_RESET  = msg_RESET;  // "RESET"
759
760     // Next check home directory
761     FGPath fntpath;
762     char* envp = ::getenv( "FG_FONTS" );
763     if ( envp != NULL ) {
764         fntpath.set( envp );
765     } else {
766         fntpath.set( current_options.get_fg_root() );
767         fntpath.append( "Fonts" );
768     }
769
770     // Install our fast fonts
771     fntpath.append( "typewriter.txf" );
772     guiFntHandle = new fntTexFont ;
773     guiFntHandle -> load ( (char *)fntpath.c_str() ) ;
774     puFont GuiFont ( guiFntHandle, 15 ) ;
775     puSetDefaultFonts( GuiFont, GuiFont ) ;
776     guiFnt = puGetDefaultLabelFont();
777   
778     if ( current_options.get_mouse_pointer() == 0 ) {
779         // no preference specified for mouse pointer, attempt to autodetect...
780         // Determine if we need to render the cursor, or if the windowing
781         // system will do it.  First test if we are rendering with glide.
782         if ( strstr ( general.get_glRenderer(), "Glide" ) ) {
783             // Test for the MESA_GLX_FX env variable
784             if ( (mesa_win_state = getenv( "MESA_GLX_FX" )) != NULL) {
785                 // test if we are fullscreen mesa/glide
786                 if ( (mesa_win_state[0] == 'f') ||
787                      (mesa_win_state[0] == 'F') ) {
788                     puShowCursor ();
789                 }
790             }
791         }
792         mouse_active = ~mouse_active;
793     } else if ( current_options.get_mouse_pointer() == 1 ) {
794         // don't show pointer
795     } else if ( current_options.get_mouse_pointer() == 2 ) {
796         // force showing pointer
797         puShowCursor();
798         mouse_active = ~mouse_active;
799     }
800
801     // Set up our Dialog Boxes
802     ConfirmExitDialogInit();
803     NewAirportInit();
804 #ifdef FG_NETWORK_OLK
805     NewNetIdInit();
806 #endif
807     mkDialogInit();
808     
809     // Make the menu bar
810     mainMenuBar = new puMenuBar ();
811     mainMenuBar -> add_submenu ("File", fileSubmenu, fileSubmenuCb);
812     mainMenuBar -> add_submenu ("Edit", editSubmenu, editSubmenuCb);
813     mainMenuBar -> add_submenu ("View", viewSubmenu, viewSubmenuCb);
814     mainMenuBar -> add_submenu ("Aircraft", aircraftSubmenu, aircraftSubmenuCb);
815     mainMenuBar -> add_submenu ("Environment", environmentSubmenu, environmentSubmenuCb);
816     mainMenuBar -> add_submenu ("Options", optionsSubmenu, optionsSubmenuCb);
817 #ifdef FG_NETWORK_OLK
818     mainMenuBar -> add_submenu ("Network", networkSubmenu, networkSubmenuCb);
819 #endif
820     mainMenuBar -> add_submenu ("Help", helpSubmenu, helpSubmenuCb);
821     mainMenuBar-> close ();
822     // Set up menu bar toggle
823     menu_on = ~0;
824 }