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