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