1 /* NIGHTFALL OpenGL Interface                                              */
2 /* Copyright (C) 2001 Rainer Wichmann & Markus Kuster                      */
3 /*                                                                         */
4 /*  This program is free software; you can redistribute it                 */
5 /*  and/or modify                                                          */
6 /*  it under the terms of the GNU General Public License as                */
7 /*  published by                                                           */
8 /*  the Free Software Foundation; either version 2 of the License, or      */
9 /*  (at your option) any later version.                                    */
10 /*                                                                         */
11 /*  This program is distributed in the hope that it will be useful,        */
12 /*  but WITHOUT ANY WARRANTY; without even the implied warranty of         */
13 /*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          */
14 /*  GNU General Public License for more details.                           */
15 /*                                                                         */
16 /*  You should have received a copy of the GNU General Public License      */
17 /*  along with this program; if not, write to the Free Software            */
18 /*  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.              */
19 
20 /* ANSI C forbids an empty source file, so put this outside                */
21 /* do nothing here if we don't have OpenGL                                 */
22 
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include "Light.h"
27 
28 #ifdef  _WITH_OPENGL
29 #include "LightGLPrefs.h"
30 
31 /* Preferences window            */
32 GtkWidget   *glPrefsWindow = NULL;
33 /* OpenGL preferences window opened        */
34 int GLPrefWinOpened = FALSE;
35 
36 /* Buttons in GL options                                     */
37 GtkWidget   *ButtonWire, *ButtonPoints, *ButtonOpaque;
38 
39 
40 
41 /* Buttons in texturing options                              */
42 GtkWidget   *ButtonTexture, *ButtonLabels, *ButtonAxes;
43 GtkWidget   *ButtonPrimTxt, *ButtonSecTxt;
44 GtkWidget   *PrimTxtLabel, *SecTxtLabel;
45 GtkWidget   *ButtonIMAGE, *ButtonGRAV, *ButtonFLUX,
46   *ButtonTEMP, *ButtonVELOCITY;
47 #ifdef HAVE_DISK
48 
49 GtkWidget   *ButtonDiskTxt,*DiskTxtLabel;
50 #endif
51 
52 /* Buttons in ok/cancel/save button bar                      */
53 GtkWidget   *ButtonCancel, *ButtonOk, *ButtonApply;
54 
55 typedef struct TempFlagsStruct {
56   int       axes;                  /* want x-,y-, z-axis (ON/OFF)       */
57   int       texture;               /* want textures (ON/OFF)            */
58   int       textype;               /* type of texture                   */
59   int       wireframe;             /* want wire frame or solid rendering*/
60   int       points;                /* use POINTS instead of QUAD_STRIP  */
61   int       labels;                /* want labels (ON/OFF)              */
62   int       TxtIsOn[3];            /* we want texturing (ON/OFF)        */
63   char      PTextFile[MAX_CFG_INLINE+1]; /* texture image file     */
64   char      STextFile[MAX_CFG_INLINE+1]; /* texture image file     */
65 #ifdef HAVE_DISK
66   char      DTextFile[MAX_CFG_INLINE+1]; /* texture image file     */
67 #endif
68 } TempFlagsHandle;
69 
70 TempFlagsHandle TempFlags; /* temporary variable to store flags */
71 
72 /****************************************************************************
73  @package   nightfall
74  @author    Markus Kuster (kuster@astro.uni-tuebingen.de)
75  @version   1.1
76  @short     Destroy the GL preferences window
77  @param     (GtkWidget) *widget  Discarded
78  @param     (gpointer)  *data    Widget to destroy
79  @return    (void)
80  @heading   Open GL Animation
81  ****************************************************************************/
GLOkPrefs(GtkWidget * widget,gpointer * data)82 void GLOkPrefs (GtkWidget *widget, gpointer *data)
83 {
84   if (GLPrefWinOpened == FALSE)
85     return;
86 
87   /* copy temporary values to global variables */
88   /* store actual setup in temporary variable */
89   Flags.axes              = TempFlags.axes;
90   Flags.texture           = TempFlags.texture;
91   Flags.textype           = TempFlags.textype;
92   Flags.wireframe         = TempFlags.wireframe;
93   Flags.points            = TempFlags.points;
94   Flags.labels            = TempFlags.labels;
95   Texture[Primary].IsOn   = TempFlags.TxtIsOn[Primary];
96   Texture[Secondary].IsOn = TempFlags.TxtIsOn[Secondary];
97 
98   strncpy(Texture[Primary].TextFile,  TempFlags.PTextFile, MAX_CFG_INLINE+1);
99   Texture[Primary].TextFile[MAX_CFG_INLINE] = '\0';
100   strncpy(Texture[Secondary].TextFile,TempFlags.STextFile, MAX_CFG_INLINE+1);
101   Texture[Secondary].TextFile[MAX_CFG_INLINE] = '\0';
102 
103 #ifdef HAVE_DISK
104   if (Flags.disk == ON) {
105       Texture[Disk].IsOn      = TempFlags.TxtIsOn[Disk];
106       strncpy(Texture[Disk].TextFile, TempFlags.DTextFile, MAX_CFG_INLINE+1);
107       Texture[Disk].TextFile[MAX_CFG_INLINE] = '\0';
108       GLInitTexture(Disk,IMAGE);
109   }
110 #endif
111 
112   GLInitTexture(Primary,   TempFlags.textype);
113   GLInitTexture(Secondary, TempFlags.textype);
114 
115   GLUpdateAll();
116   GLDisplayAll();
117   GLUpdateAll();
118   GLDisplayAll();
119 
120   gtk_widget_destroy (GTK_WIDGET (glPrefsWindow));
121   GLPrefWinOpened = FALSE;
122 
123   return;
124 }
125 
126 /****************************************************************************
127  @package   nightfall
128  @author    Markus Kuster (kuster@astro.uni-tuebingen.de)
129  @version   1.1
130  @short     Destroy the GL preferences window
131  @param     (GtkWidget) *widget  Discarded
132  @param     (gpointer)  *data    Widget to destroy
133  @return    (void)
134  @heading   Open GL Animation
135  ****************************************************************************/
GLApplyPrefs(GtkWidget * widget,gpointer * data)136 void GLApplyPrefs (GtkWidget *widget, gpointer *data)
137 {
138   if (GLPrefWinOpened == FALSE)
139     return;
140 
141   /* set temporary values as new values */
142   Flags.axes              = TempFlags.axes;
143   Flags.texture           = TempFlags.texture;
144   Flags.textype           = TempFlags.textype;
145   Flags.wireframe         = TempFlags.wireframe;
146   Flags.points            = TempFlags.points;
147   Flags.labels            = TempFlags.labels;
148   Texture[Primary].IsOn   = TempFlags.TxtIsOn[Primary];
149   Texture[Secondary].IsOn = TempFlags.TxtIsOn[Secondary];
150 
151   strncpy(Texture[Primary].TextFile,   TempFlags.PTextFile,MAX_CFG_INLINE+1);
152   Texture[Primary].TextFile[MAX_CFG_INLINE] = '\0';
153   strncpy(Texture[Secondary].TextFile, TempFlags.STextFile,MAX_CFG_INLINE+1);
154   Texture[Secondary].TextFile[MAX_CFG_INLINE] = '\0';
155 
156 #ifdef HAVE_DISK
157   if (Flags.disk == ON) {
158       Texture[Disk].IsOn      = TempFlags.TxtIsOn[Disk];
159       strncpy(Texture[Disk].TextFile, TempFlags.DTextFile, MAX_CFG_INLINE+1);
160       Texture[Disk].TextFile[MAX_CFG_INLINE] = '\0';
161       GLInitTexture(Disk,IMAGE);
162   }
163 #endif
164 
165   GLInitTexture(Primary,   TempFlags.textype);
166   GLInitTexture(Secondary, TempFlags.textype);
167 
168   GLUpdateAll();
169   GLDisplayAll();
170   return;
171 }
172 
173 /****************************************************************************
174  @package   nightfall
175  @author    Markus Kuster (kuster@astro.uni-tuebingen.de)
176  @version   1.0
177  @short     Destroy the GL preferences window
178  @param     (GtkWidget) *widget  Discarded
179  @param     (gpointer)  *data    Widget to destroy
180  @return    (void)
181  @heading   Open GL Animation
182  ****************************************************************************/
GLDeletePrefs(GtkWidget * widget,gpointer * data)183 void GLDeletePrefs (GtkWidget *widget, gpointer *data)
184 {
185   if (GLPrefWinOpened == FALSE)
186     return;
187 
188   gtk_widget_destroy (GTK_WIDGET (glPrefsWindow));
189   GLPrefWinOpened = FALSE;
190 
191   return;
192 }
193 
194 /****************************************************************************
195  @package   nightfall
196  @author    Markus Kuster (kuster@astro.uni-tuebingen.de)
197  @version   1.0
198  @short     Destroy the GL preferences window
199  @param     (GtkWidget) *widget  Discarded
200  @param     (gpointer)  *data    Widget to destroy
201  @return    (void)
202  @heading   Open GL Animation
203  ****************************************************************************/
GLLabelsEvent(GtkWidget * widget,gpointer * data)204 void GLLabelsEvent (GtkWidget *widget, gpointer *data)
205 {
206   if(GTK_TOGGLE_BUTTON (widget)->active) {
207     TempFlags.labels = ON;
208   } else {
209     TempFlags.labels = OFF;
210   }
211 
212   return;
213 }
214 
215 /******************************************************************
216  @package   nightfall
217  @author    Markus Kuster (kuster@astro.uni-tuebingen.de)
218  @version   1.0
219  @short     Callback function for 'axis on/off'
220  @param     (GtkWidget) *widget     Discarded
221  @param     (gpointer)  *data       Discarded
222  @return    (void)
223  @heading
224 *******************************************************************/
GLAxesEvent(GtkWidget * widget,gpointer * data)225 void GLAxesEvent (GtkWidget *widget, gpointer *data)
226 {
227   if(GTK_TOGGLE_BUTTON (widget)->active) {
228     TempFlags.axes = ON;
229   } else {
230     TempFlags.axes = OFF;
231   }
232 
233   return;
234 }
235 
236 /******************************************************************
237  @package   nightfall
238  @author    Markus Kuster (kuster@astro.uni-tuebingen.de)
239  @version   1.0
240  @short     Callback function for 'wire frame on/off'
241  @param     (GtkWidget) *widget     Discarded
242  @param     (gpointer)  *data       Discarded
243  @return    (void)
244  @heading
245 *******************************************************************/
GLFilledEvent(GtkWidget * widget,gpointer * data)246 void GLFilledEvent (GtkWidget *widget, gpointer *data)
247 {
248   if(GTK_TOGGLE_BUTTON (widget)->active) {
249     TempFlags.wireframe = ON;
250     TempFlags.points    = OFF;
251   }
252   return;
253 }
254 
255 /******************************************************************
256  @package   nightfall
257  @author    Markus Kuster (kuster@astro.uni-tuebingen.de)
258  @version   1.1
259  @short     Callback function for 'texturing on/off'
260  @param     (GtkWidget) *widget     Discarded
261  @param     (gpointer)  *data       Discarded
262  @return    (void)
263  @heading
264 *******************************************************************/
GLTextureEvent(GtkWidget * widget,gpointer * data)265 void GLTextureEvent (GtkWidget *widget, gpointer *data)
266 {
267   if(GTK_TOGGLE_BUTTON (widget)->active) {
268     TempFlags.texture = ON;
269     gtk_widget_set_sensitive(ButtonPrimTxt,TRUE);
270     gtk_widget_set_sensitive(ButtonSecTxt,TRUE);
271     gtk_widget_set_sensitive(PrimTxtLabel,TRUE);
272     gtk_widget_set_sensitive(SecTxtLabel,TRUE);
273 #ifdef HAVE_DISK
274     if (Flags.disk == ON) {
275 	gtk_widget_set_sensitive(ButtonDiskTxt,TRUE);
276 	gtk_widget_set_sensitive(DiskTxtLabel,TRUE);
277     }
278 #endif
279   } else {
280     TempFlags.texture = OFF;
281     gtk_widget_set_sensitive(ButtonPrimTxt,FALSE);
282     gtk_widget_set_sensitive(ButtonSecTxt,FALSE);
283     gtk_widget_set_sensitive(PrimTxtLabel,FALSE);
284     gtk_widget_set_sensitive(SecTxtLabel,FALSE);
285 #ifdef HAVE_DISK
286     if (Flags.disk == ON) {
287 	gtk_widget_set_sensitive(ButtonDiskTxt,FALSE);
288 	gtk_widget_set_sensitive(DiskTxtLabel,FALSE);
289     }
290 #endif
291   }
292 
293   return;
294 }
295 
296 /******************************************************************
297  @package   nightfall
298  @author    Markus Kuster (kuster@astro.uni-tuebingen.de)
299  @version   1.0
300  @short     Callback function for 'primary texture on/off'
301  @param     (GtkWidget) *widget     Discarded
302  @param     (gpointer)  *data       Discarded
303  @return    (void)
304  @heading
305 *******************************************************************/
GLPrimTextureEvent(GtkWidget * widget,gpointer * data)306 void GLPrimTextureEvent (GtkWidget *widget, gpointer *data)
307 {
308   if(GTK_TOGGLE_BUTTON (widget)->active) {
309     /*Texture[Primary].IsOn = ON;*/
310     TempFlags.TxtIsOn[Primary] = ON;
311   } else {
312     /*Texture[Primary].IsOn = OFF;*/
313     TempFlags.TxtIsOn[Primary] = OFF;
314   }
315   return;
316 }
317 
318 /******************************************************************
319  @package   nightfall
320  @author    Markus Kuster (kuster@astro.uni-tuebingen.de)
321  @version   1.0
322  @short     Callback function for input primary texture file
323  @param     (GtkWidget) *widget     Discarded
324  @param     (gpointer)  *data       Discarded
325  @return    (void)
326  @heading
327 *******************************************************************/
GLEnterPrimTxt(GtkWidget * widget,gpointer * entry)328 void GLEnterPrimTxt (GtkWidget *widget, gpointer *entry)
329 {
330   const gchar *entry_text;
331   TempFlagsHandle *TexPtr=NULL;
332 
333   TexPtr=&TempFlags;
334 
335   entry_text = gtk_entry_get_text(GTK_ENTRY(entry));
336   snprintf(TexPtr->PTextFile, MAX_CFG_INLINE+1, "%s", entry_text);
337 
338   return;
339 }
340 
341 /******************************************************************
342  @package   nightfall
343  @author    Markus Kuster (kuster@astro.uni-tuebingen.de)
344  @version   1.0
345  @short     Callback function for 'secondary texture on/off'
346  @param     (GtkWidget) *widget     Discarded
347  @param     (gpointer)  *data       Discarded
348  @return    (void)
349  @heading
350 *******************************************************************/
GLSecTextureEvent(GtkWidget * widget,gpointer * data)351 void GLSecTextureEvent (GtkWidget *widget, gpointer *data)
352 {
353   if(GTK_TOGGLE_BUTTON (widget)->active) {
354     /*Texture[Secondary].IsOn = ON;*/
355     TempFlags.TxtIsOn[Secondary] = ON;
356   } else {
357     /*Texture[Secondary].IsOn = OFF;*/
358     TempFlags.TxtIsOn[Secondary] = OFF;
359   }
360 
361   return;
362 }
363 
364 /******************************************************************
365  @package   nightfall
366  @author    Markus Kuster (kuster@astro.uni-tuebingen.de)
367  @version   1.0
368  @short     Callback function for inputsecondary texture file
369  @param     (GtkWidget) *widget     Discarded
370  @param     (gpointer)  *data       Discarded
371  @return    (void)
372  @heading
373 *******************************************************************/
GLEnterSecTxt(GtkWidget * widget,gpointer * entry)374 void GLEnterSecTxt (GtkWidget *widget, gpointer *entry)
375 {
376   const gchar *entry_text;
377   TempFlagsHandle *TexPtr=NULL;
378 
379   TexPtr=&TempFlags;
380 
381   entry_text = gtk_entry_get_text(GTK_ENTRY(entry));
382   snprintf(TexPtr->STextFile, MAX_CFG_INLINE+1, "%s", entry_text);
383 
384   return;
385 }
386 
387 #ifdef HAVE_DISK
388 /******************************************************************
389  @package   nightfall
390  @author    Markus Kuster (kuster@astro.uni-tuebingen.de)
391  @version   1.0
392  @short     Callback function for 'disk texture on/off'
393  @param     (GtkWidget) *widget     Discarded
394  @param     (gpointer)  *data       Discarded
395  @return    (void)
396  @heading
397 *******************************************************************/
GLDiskTextureEvent(GtkWidget * widget,gpointer * data)398 void GLDiskTextureEvent (GtkWidget *widget, gpointer *data)
399 {
400   if(GTK_TOGGLE_BUTTON (widget)->active) {
401     /*Texture[Disk].IsOn = ON;*/
402     TempFlags.TxtIsOn[Disk] = ON;
403   } else {
404     /*Texture[Disk].IsOn = OFF;*/
405     TempFlags.TxtIsOn[Disk] = OFF;
406   }
407 
408   return;
409 }
410 
411 /******************************************************************
412  @package   nightfall
413  @author    Markus Kuster (kuster@astro.uni-tuebingen.de)
414  @version   1.0
415  @short     Callback function for input disk texture file
416  @param     (GtkWidget) *widget     Discarded
417  @param     (gpointer)  *data       Discarded
418  @return    (void)
419  @heading
420 *******************************************************************/
GLEnterDiskTxt(GtkWidget * widget,gpointer * entry)421 void GLEnterDiskTxt (GtkWidget *widget, gpointer *entry)
422 {
423   const gchar *entry_text;
424   TempFlagsHandle *TexPtr=NULL;
425 
426   TexPtr=&TempFlags;
427 
428   entry_text = gtk_entry_get_text(GTK_ENTRY(entry));
429   snprintf(TexPtr->DTextFile, MAX_CFG_INLINE+1, "%s", entry_text);
430 
431   return;
432 }
433 #endif
434 
435 /******************************************************************
436  @package   nightfall
437  @author    Markus Kuster (kuster@astro.uni-tuebingen.de)
438  @version   1.0
439  @short     Callback function for 'GL_POINTS on/off'
440  @param     (GtkWidget) *widget     Discarded
441  @param     (gpointer)  *data       Discarded
442  @return    (void)
443  @heading
444 *******************************************************************/
GLPointsEvent(GtkWidget * widget,gpointer * data)445 void GLPointsEvent (GtkWidget *widget, gpointer *data)
446 {
447   if(GTK_TOGGLE_BUTTON (widget)->active) {
448     TempFlags.points    = ON;
449     TempFlags.wireframe = OFF;
450   }
451 
452   return;
453 }
454 
455 /******************************************************************
456  @package   nightfall
457  @author    Rainer Wichmann (rwichmann@lsw.uni-heidelberg.de)
458  @version   1.0
459  @short     Callback function for 'textype setting'
460  @param     (GtkWidget) *widget     Discarded
461  @param     (gpointer)  *data       textype
462  @return    (void)
463  @heading
464 *******************************************************************/
GLTexTypeEvent(GtkWidget * widget,gpointer * data)465 void GLTexTypeEvent (GtkWidget *widget, gpointer *data)
466 {
467   if(GTK_TOGGLE_BUTTON (widget)->active) {
468     TempFlags.textype   = GPOINTER_TO_INT(data);
469   }
470   return;
471 }
472 
473 /******************************************************************
474  @package   nightfall
475  @author    Rainer Wichmann (rwichmann@lsw.uni-heidelberg.de)
476  @version   1.0
477  @short     Callback function for 'solid on/off'
478  @param     (GtkWidget) *widget     Discarded
479  @param     (gpointer)  *data       Discarded
480  @return    (void)
481  @heading
482 *******************************************************************/
GLOpaqueEvent(GtkWidget * widget,gpointer * data)483 void GLOpaqueEvent (GtkWidget *widget, gpointer *data)
484 {
485   if(GTK_TOGGLE_BUTTON (widget)->active) {
486     TempFlags.points = OFF;
487     TempFlags.wireframe = OFF;
488   }
489 
490   return;
491 }
492 
493 /******************************************************************
494  @package   nightfall
495  @author    Markus Kuster (kuster@astro.uni-tuebingen.de)
496  @version   1.0
497  @short     Preferences window for OpenGL
498  @param     (void)
499  @return    (void)
500  @heading   Open GL Animation
501 *******************************************************************/
GLPrefs(void)502 void GLPrefs(void)
503 {
504   char        InitString[4096];          /* init string for entry field */
505   GtkWidget   *glBaseVBox;    /* Vertical box for all frames   */
506   GtkWidget   *glOptHBox;     /* Horizontal box for GL options */
507   GtkWidget   *glTxtHBox;     /* Horizontal box for texture options   */
508   GtkWidget   *glTypHBox;     /* Horizontal box for textyp options */
509   GtkWidget   *glDispOptHBox; /* Horizontal box for display options   */
510   GtkWidget   *glButtonHBox;  /* Horizontal box for Close/Cancel buttons */
511 
512 
513 
514   GtkWidget   *OptFrame;
515   GtkWidget   *TxtFrame;
516   GtkWidget   *DispOptFrame;
517 
518   GtkWidget   *glOptTable;
519   GtkWidget   *glTxtTable;
520   GtkWidget   *glDispOptTable;
521 
522   GSList      *group;
523 
524   GtkTooltips *tooltips;
525 
526 
527   /* store actual setup in temporary variable */
528   TempFlags.axes                 = Flags.axes;
529   TempFlags.texture              = Flags.texture;
530   TempFlags.textype              = Flags.textype;
531   TempFlags.wireframe            = Flags.wireframe;
532   TempFlags.points               = Flags.points;
533   TempFlags.labels               = Flags.labels;
534   TempFlags.TxtIsOn[Primary]     = Texture[Primary].IsOn;
535   TempFlags.TxtIsOn[Secondary]   = Texture[Secondary].IsOn;
536   strncpy(TempFlags.PTextFile, Texture[Primary].TextFile,   MAX_CFG_INLINE+1);
537   Texture[Primary].TextFile[MAX_CFG_INLINE] = '\0';
538   strncpy(TempFlags.STextFile, Texture[Secondary].TextFile, MAX_CFG_INLINE+1);
539   Texture[Secondary].TextFile[MAX_CFG_INLINE] = '\0';
540 #ifdef HAVE_DISK
541   if (Flags.disk == ON) {
542       TempFlags.TxtIsOn[Disk]        = Texture[Disk].IsOn;
543       strncpy(TempFlags.DTextFile, Texture[Disk].TextFile, MAX_CFG_INLINE+1);
544       Texture[Disk].TextFile[MAX_CFG_INLINE] = '\0';
545   }
546 #endif
547 
548   tooltips = gtk_tooltips_new ();
549   gtk_tooltips_set_delay  (tooltips, 1800);
550 
551   /* >>>>>>>>>>>>>>>>>>>>>  MAKE WIDGET     <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< */
552 
553   glPrefsWindow = gtk_window_new (GTK_WINDOW_TOPLEVEL);
554 
555   gtk_window_set_position(GTK_WINDOW(glPrefsWindow), GTK_WIN_POS_MOUSE);
556 
557 #ifdef USING_GTK2
558   gtk_window_set_resizable(GTK_WINDOW(glPrefsWindow), TRUE);
559 #else
560   gtk_window_set_policy (GTK_WINDOW(glPrefsWindow), FALSE, FALSE, TRUE);
561 #endif
562 
563   gtk_signal_connect (GTK_OBJECT (glPrefsWindow), "delete_event",
564 		      GTK_SIGNAL_FUNC (GLDeletePrefs),
565 		      GTK_WIDGET (glPrefsWindow));
566 
567   gtk_window_set_title (GTK_WINDOW (glPrefsWindow), _("Display Preferences") );
568   gtk_container_set_border_width (GTK_CONTAINER (glPrefsWindow), 0);
569   gtk_widget_show (glPrefsWindow);
570 
571   /* Vertical Box containing all                      */
572   glBaseVBox  = gtk_vbox_new (FALSE, 0);
573   gtk_container_set_border_width (GTK_CONTAINER (glBaseVBox), 4);
574   gtk_container_add(GTK_CONTAINER (glPrefsWindow), GTK_WIDGET(glBaseVBox));
575   gtk_widget_show (glBaseVBox);
576 
577   /* --------------------------------------------------------------------- */
578   /* Create GL Options frame                          */
579   OptFrame = gtk_frame_new (_("GL Options") );
580   gtk_container_add (GTK_CONTAINER (glBaseVBox), OptFrame);
581   gtk_container_set_border_width(GTK_CONTAINER(OptFrame), 2);
582   gtk_widget_show (OptFrame);
583 
584   /* Start with GL Options frame                      */
585   glOptHBox = gtk_hbox_new (TRUE, 0);
586   gtk_container_add (GTK_CONTAINER (OptFrame), glOptHBox);
587   gtk_container_set_border_width (GTK_CONTAINER (glOptHBox), 4);
588   gtk_widget_show (glOptHBox);
589 
590   glOptTable = gtk_table_new (1, 2, TRUE);
591 
592   /* GLPoints button                      */
593   ButtonPoints = gtk_radio_button_new_with_label (NULL, _("Points") );
594   if (Flags.points == ON)
595     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (ButtonPoints), TRUE);
596   gtk_tooltips_set_tip (tooltips, ButtonPoints,
597 			_("Display visible surface elements using points"),
598 			NULL);
599   gtk_signal_connect (GTK_OBJECT (ButtonPoints), "toggled",
600                       (GtkSignalFunc) GLPointsEvent,
601                       (gpointer) "0");
602   gtk_table_attach (GTK_TABLE(glOptTable),ButtonPoints, 0, 1, 0, 1,
603 		    GTK_FILL|GTK_EXPAND, GTK_FILL|GTK_EXPAND, 2, 2);
604   gtk_widget_show (ButtonPoints);
605 
606   group  = gtk_radio_button_group (GTK_RADIO_BUTTON (ButtonPoints));
607 
608   /* Wire frame button                      */
609   ButtonWire = gtk_radio_button_new_with_label (group, _("Wire Frame") );
610   if (Flags.wireframe == ON)
611     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (ButtonWire), TRUE);
612   gtk_tooltips_set_tip (tooltips, ButtonWire,
613 			_("Display objects as wire frame"),
614 			NULL);
615   gtk_signal_connect (GTK_OBJECT (ButtonWire), "clicked",
616                       (GtkSignalFunc) GLFilledEvent,
617                       (gpointer) "0");
618   gtk_table_attach (GTK_TABLE(glOptTable), ButtonWire, 1, 2, 0, 1,
619 		    GTK_FILL|GTK_EXPAND, GTK_FILL|GTK_EXPAND, 2, 2);
620   gtk_widget_show (ButtonWire);
621 
622   group  = gtk_radio_button_group (GTK_RADIO_BUTTON (ButtonWire));
623 
624   /* Solid button                      */
625   ButtonOpaque = gtk_radio_button_new_with_label (group, _("Opaque") );
626   if (Flags.wireframe == OFF && Flags.points == OFF)
627     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (ButtonOpaque), TRUE);
628   gtk_tooltips_set_tip (tooltips, ButtonOpaque,
629 			_("Display objects in opaque mode"),
630 			NULL);
631   gtk_signal_connect (GTK_OBJECT (ButtonOpaque), "toggled",
632                       (GtkSignalFunc) GLOpaqueEvent,
633                       (gpointer) "0");
634   gtk_table_attach (GTK_TABLE(glOptTable), ButtonOpaque, 2, 3, 0, 1,
635 		    GTK_FILL|GTK_EXPAND, GTK_FILL|GTK_EXPAND, 2, 2);
636   gtk_widget_show (ButtonOpaque);
637 
638 
639   /* show the table                     */
640   gtk_box_pack_start (GTK_BOX (glOptHBox), glOptTable, FALSE, FALSE, 0);
641   gtk_widget_show(glOptTable);
642 
643   /* --------------------------------------------------------------------- */
644 
645   /* Create Texture Options frame                     */
646   TxtFrame = gtk_frame_new (_("Texture Options") );
647   gtk_container_add (GTK_CONTAINER (glBaseVBox), TxtFrame);
648   gtk_container_set_border_width(GTK_CONTAINER(TxtFrame), 2);
649   gtk_widget_show (TxtFrame);
650 
651   /* Start with Texture Options frame                      */
652   glTxtHBox = gtk_hbox_new (TRUE, 0);
653   gtk_container_add (GTK_CONTAINER (TxtFrame), glTxtHBox);
654   gtk_container_set_border_width (GTK_CONTAINER (glTxtHBox), 4);
655   gtk_widget_show (glTxtHBox);
656 
657   glTxtTable = gtk_table_new (5, 2, TRUE);
658 
659   /* show the table                                                        */
660   gtk_box_pack_start (GTK_BOX (glTxtHBox), glTxtTable, FALSE, FALSE, 0);
661   gtk_widget_show (glTxtTable);
662 
663   /* texture ON/OFF button                      */
664   ButtonTexture = gtk_check_button_new_with_label (_("Textures") );
665   if (Flags.texture == ON)
666     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (ButtonTexture), TRUE);
667   gtk_tooltips_set_tip (tooltips, ButtonTexture,
668 			_("Switch texturing on"), NULL);
669   gtk_signal_connect (GTK_OBJECT (ButtonTexture), "clicked",
670                       (GtkSignalFunc) GLTextureEvent,
671                       (gpointer) "0");
672   gtk_table_attach (GTK_TABLE(glTxtTable), ButtonTexture, 0, 1, 0, 1,
673 		    GTK_FILL|GTK_EXPAND, GTK_FILL|GTK_EXPAND, 2, 2);
674   gtk_widget_show (ButtonTexture);
675 
676   /* Primary texture button                      */
677   ButtonPrimTxt = gtk_check_button_new_with_label (_("Primary Texture On/Off") );
678   if (Texture[Primary].IsOn == ON)
679     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (ButtonPrimTxt), TRUE);
680   gtk_tooltips_set_tip (tooltips, ButtonPrimTxt,
681 			_("Toggle primary texture On/Off"), NULL);
682   gtk_signal_connect (GTK_OBJECT (ButtonPrimTxt), "clicked",
683                       (GtkSignalFunc) GLPrimTextureEvent,
684                       (gpointer) "0");
685   gtk_table_attach (GTK_TABLE(glTxtTable), ButtonPrimTxt, 0, 1, 1, 2,
686 		    GTK_FILL|GTK_EXPAND, GTK_FILL|GTK_EXPAND, 2, 2);
687   gtk_widget_show (ButtonPrimTxt);
688   if (Flags.texture == OFF)
689     gtk_widget_set_sensitive(ButtonPrimTxt,FALSE);
690 
691   PrimTxtLabel = gtk_entry_new_with_max_length (256);
692   gtk_tooltips_set_tip (tooltips, PrimTxtLabel,
693 			_("Image file used as texture for primary"), NULL);
694   gtk_signal_connect(GTK_OBJECT(PrimTxtLabel), "changed",
695 		     GTK_SIGNAL_FUNC(GLEnterPrimTxt),
696 		     PrimTxtLabel);
697   sprintf(InitString, "%s", Texture[Primary].TextFile);
698   gtk_entry_set_text (GTK_ENTRY (PrimTxtLabel), InitString);
699   gtk_entry_select_region (GTK_ENTRY (PrimTxtLabel),
700 			   0, GTK_ENTRY(PrimTxtLabel)->text_length);
701   gtk_table_attach (GTK_TABLE(glTxtTable), PrimTxtLabel, 1, 2, 1, 2,
702 		    GTK_FILL|GTK_EXPAND, GTK_FILL|GTK_EXPAND, 2, 2);
703   gtk_widget_show (PrimTxtLabel);
704   if (Flags.texture == OFF)
705     gtk_widget_set_sensitive(PrimTxtLabel,FALSE);
706 
707   /* Secondary texture button                      */
708   ButtonSecTxt = gtk_check_button_new_with_label (_("Secondary Texture On/Off") );
709   if (Texture[Secondary].IsOn == ON)
710     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (ButtonSecTxt), TRUE);
711   gtk_tooltips_set_tip (tooltips, ButtonSecTxt,
712 			_("Toggle secondary texture On/Off"), NULL);
713   gtk_signal_connect (GTK_OBJECT (ButtonSecTxt), "clicked",
714                       (GtkSignalFunc) GLSecTextureEvent,
715                       (gpointer) "0");
716   gtk_table_attach (GTK_TABLE(glTxtTable), ButtonSecTxt, 0, 1, 2, 3,
717 		    GTK_FILL|GTK_EXPAND, GTK_FILL|GTK_EXPAND, 2, 2);
718   gtk_widget_show (ButtonSecTxt);
719   if (Flags.texture == OFF)
720     gtk_widget_set_sensitive(ButtonSecTxt,FALSE);
721 
722   SecTxtLabel = gtk_entry_new_with_max_length (256);
723   gtk_tooltips_set_tip (tooltips, SecTxtLabel,
724 			_("Image file used as texture for secondary"), NULL);
725   gtk_signal_connect(GTK_OBJECT(SecTxtLabel), "changed",
726 		     GTK_SIGNAL_FUNC(GLEnterSecTxt),
727 		     SecTxtLabel);
728   sprintf(InitString, "%s", Texture[Secondary].TextFile);
729   gtk_entry_set_text (GTK_ENTRY (SecTxtLabel), InitString);
730   gtk_entry_select_region (GTK_ENTRY (SecTxtLabel),
731 			   0, GTK_ENTRY(SecTxtLabel)->text_length);
732   gtk_table_attach (GTK_TABLE(glTxtTable), SecTxtLabel, 1, 2, 2, 3,
733 		    GTK_FILL|GTK_EXPAND, GTK_FILL|GTK_EXPAND, 2, 2);
734   gtk_widget_show (SecTxtLabel);
735   if (Flags.texture == OFF)
736     gtk_widget_set_sensitive(SecTxtLabel,FALSE);
737 
738 #ifdef HAVE_DISK
739   if (Flags.disk == ON) {
740   /* Disk texture button                      */
741       ButtonDiskTxt = gtk_check_button_new_with_label (_("Disk Texture On/Off") );
742       if ( Texture[Disk].IsOn == ON)
743 	  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (ButtonDiskTxt), TRUE);
744       gtk_tooltips_set_tip (tooltips, ButtonDiskTxt,
745 			    _("Toggle disk texture On/Off"), NULL);
746       gtk_signal_connect (GTK_OBJECT (ButtonDiskTxt), "clicked",
747 			  (GtkSignalFunc) GLDiskTextureEvent,
748 			  (gpointer) "0");
749       gtk_table_attach (GTK_TABLE(glTxtTable), ButtonDiskTxt, 0, 1, 3, 4,
750 			GTK_FILL|GTK_EXPAND, GTK_FILL|GTK_EXPAND, 2, 2);
751       gtk_widget_show (ButtonDiskTxt);
752       if (Flags.texture == OFF)
753 	  gtk_widget_set_sensitive(ButtonDiskTxt,FALSE);
754 
755       DiskTxtLabel = gtk_entry_new_with_max_length (256);
756       gtk_tooltips_set_tip (tooltips, DiskTxtLabel,
757 			    _("Image file used as texture for disk"), NULL);
758       gtk_signal_connect(GTK_OBJECT(DiskTxtLabel), "changed",
759 			 GTK_SIGNAL_FUNC(GLEnterDiskTxt),
760 			 DiskTxtLabel);
761       sprintf(InitString, "%s", Texture[Disk].TextFile);
762       gtk_entry_set_text (GTK_ENTRY (DiskTxtLabel), InitString);
763       gtk_entry_select_region (GTK_ENTRY (DiskTxtLabel),
764 			   0, GTK_ENTRY(DiskTxtLabel)->text_length);
765       gtk_table_attach (GTK_TABLE(glTxtTable), DiskTxtLabel, 1, 2, 3, 4,
766 			GTK_FILL|GTK_EXPAND, GTK_FILL|GTK_EXPAND, 2, 2);
767       gtk_widget_show (DiskTxtLabel);
768       if (Flags.texture == OFF)
769 	  gtk_widget_set_sensitive(DiskTxtLabel,FALSE);
770   }
771 #endif
772 
773 
774   /* --------------------------------------------------------------------- */
775 
776   /* Start with Textyp Options                      */
777   glTypHBox = gtk_hbox_new (TRUE, 0);
778   gtk_table_attach (GTK_TABLE(glTxtTable), glTypHBox, 0, 2, 4, 5,
779 		    GTK_FILL|GTK_EXPAND, GTK_FILL|GTK_EXPAND, 2, 2);
780   gtk_widget_show (glTypHBox);
781 
782   /* GLPoints button                      */
783   ButtonIMAGE = gtk_radio_button_new_with_label (NULL, _("Image") );
784   if (Flags.textype == IMAGE)
785     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (ButtonIMAGE), TRUE);
786   gtk_tooltips_set_tip (tooltips, ButtonIMAGE,
787 			_("Use image for texture"),
788 			NULL);
789   gtk_signal_connect (GTK_OBJECT (ButtonIMAGE), "clicked",
790                       (GtkSignalFunc) GLTexTypeEvent,
791                       GINT_TO_POINTER((gint) IMAGE));
792   gtk_box_pack_start (GTK_BOX (glTypHBox), ButtonIMAGE, FALSE, FALSE, 0);
793   gtk_widget_show (ButtonIMAGE);
794 
795   group  = gtk_radio_button_group (GTK_RADIO_BUTTON (ButtonIMAGE));
796 
797   /* Wire frame button                      */
798   ButtonFLUX = gtk_radio_button_new_with_label (group, _("Flux") );
799   if (Flags.textype == FLUX)
800     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (ButtonFLUX), TRUE);
801   gtk_tooltips_set_tip (tooltips, ButtonFLUX,
802 			_("Use flux for texture"),
803 			NULL);
804   gtk_signal_connect (GTK_OBJECT (ButtonFLUX), "clicked",
805                       (GtkSignalFunc) GLTexTypeEvent,
806                       GINT_TO_POINTER((gint) FLUX));
807   gtk_box_pack_start (GTK_BOX (glTypHBox), ButtonFLUX, FALSE, FALSE, 0);
808   gtk_widget_show (ButtonFLUX);
809 
810   group  = gtk_radio_button_group (GTK_RADIO_BUTTON (ButtonFLUX));
811 
812   /* Wire frame button                      */
813   ButtonTEMP = gtk_radio_button_new_with_label (group, _("Temperature") );
814   if (Flags.textype == TEMP)
815     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (ButtonTEMP), TRUE);
816   gtk_tooltips_set_tip (tooltips, ButtonTEMP,
817 			_("Use temperature for texture"),
818 			NULL);
819   gtk_signal_connect (GTK_OBJECT (ButtonTEMP), "clicked",
820                       (GtkSignalFunc) GLTexTypeEvent,
821                       GINT_TO_POINTER((gint) TEMP));
822   gtk_box_pack_start (GTK_BOX (glTypHBox), ButtonTEMP, FALSE, FALSE, 0);
823   gtk_widget_show (ButtonTEMP);
824 
825   group  = gtk_radio_button_group (GTK_RADIO_BUTTON (ButtonTEMP));
826 
827   /* Wire frame button                      */
828   ButtonGRAV = gtk_radio_button_new_with_label (group, _("Gravity") );
829   if (Flags.textype == GRAV)
830     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (ButtonGRAV), TRUE);
831   gtk_tooltips_set_tip (tooltips, ButtonGRAV,
832 			_("Use surface gravity for texture"),
833 			NULL);
834   gtk_signal_connect (GTK_OBJECT (ButtonGRAV), "clicked",
835                       (GtkSignalFunc) GLTexTypeEvent,
836                       GINT_TO_POINTER((gint) GRAV));
837   gtk_box_pack_start (GTK_BOX (glTypHBox), ButtonGRAV, FALSE, FALSE, 0);
838   gtk_widget_show (ButtonGRAV);
839 
840   group  = gtk_radio_button_group (GTK_RADIO_BUTTON (ButtonGRAV));
841 
842   /* Wire frame button                      */
843   ButtonVELOCITY = gtk_radio_button_new_with_label (group, _("Velocity") );
844   if (Flags.textype == VELOCITY)
845     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (ButtonVELOCITY), TRUE);
846   gtk_tooltips_set_tip (tooltips, ButtonVELOCITY,
847 			_("Use radial velocity for texture"),
848 			NULL);
849   gtk_signal_connect (GTK_OBJECT (ButtonVELOCITY), "clicked",
850                       (GtkSignalFunc) GLTexTypeEvent,
851                       GINT_TO_POINTER((gint) VELOCITY));
852   gtk_box_pack_start (GTK_BOX (glTypHBox), ButtonVELOCITY, FALSE, FALSE, 0);
853   gtk_widget_show (ButtonVELOCITY);
854 
855   group  = gtk_radio_button_group (GTK_RADIO_BUTTON (ButtonVELOCITY));
856 
857 
858   /* --------------------------------------------------------------------- */
859 
860   /* --------------------------------------------------------------------- */
861 
862   /* Display Options frame                     */
863   DispOptFrame = gtk_frame_new (_("Display Options") );
864   gtk_container_add (GTK_CONTAINER (glBaseVBox), DispOptFrame);
865   gtk_container_set_border_width(GTK_CONTAINER(DispOptFrame), 2);
866   gtk_widget_show (DispOptFrame);
867 
868   glDispOptTable = gtk_table_new (1, 2, TRUE);
869 
870   /* Start with display options frame                      */
871   glDispOptHBox = gtk_hbox_new (TRUE, 0);
872   gtk_container_add (GTK_CONTAINER (DispOptFrame), glDispOptHBox);
873   gtk_container_set_border_width (GTK_CONTAINER (glDispOptHBox), 4);
874   gtk_widget_show (glDispOptHBox);
875 
876   /* Label button                      */
877   ButtonLabels = gtk_check_button_new_with_label (_("Show Labels") );
878   if (Flags.labels == ON)
879     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (ButtonLabels), TRUE);
880   gtk_tooltips_set_tip (tooltips, ButtonLabels,
881 			_("Show labels for the components"), NULL);
882   gtk_signal_connect (GTK_OBJECT (ButtonLabels), "clicked",
883                       (GtkSignalFunc) GLLabelsEvent,
884                       (gpointer) "0");
885   gtk_table_attach (GTK_TABLE(glDispOptTable),ButtonLabels, 0, 1, 0, 1,
886 		    GTK_FILL|GTK_EXPAND, GTK_FILL|GTK_EXPAND, 2, 2);
887   gtk_widget_show (ButtonLabels);
888 
889   /* Axes button */
890   ButtonAxes = gtk_check_button_new_with_label (_("Show Axes") );
891   if (Flags.axes == ON)
892     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (ButtonAxes), TRUE);
893   gtk_tooltips_set_tip (tooltips, ButtonAxes,
894 			_("Show x,y,z axes"), NULL);
895   gtk_signal_connect (GTK_OBJECT (ButtonAxes), "clicked",
896                       (GtkSignalFunc) GLAxesEvent,
897                       (gpointer) "0");
898   gtk_table_attach (GTK_TABLE(glDispOptTable),ButtonAxes, 1, 2, 0, 1,
899 		    GTK_FILL|GTK_EXPAND, GTK_FILL|GTK_EXPAND, 2, 2);
900   gtk_widget_show (ButtonAxes);
901 
902   gtk_box_pack_start (GTK_BOX (glDispOptHBox), glDispOptTable, FALSE, FALSE, 0);
903   gtk_widget_show(glDispOptTable);
904 
905   /* --------------------------------------------------------------------- */
906 
907   /* Create button bar                                               */
908 
909   /* Start with GL Options frame                                     */
910   glButtonHBox = gtk_hbox_new (TRUE, 0);
911   gtk_container_add (GTK_CONTAINER (glBaseVBox), glButtonHBox);
912   gtk_container_set_border_width (GTK_CONTAINER (glButtonHBox), 4);
913   gtk_widget_show (glButtonHBox);
914 
915   /* Ok button                                                       */
916   ButtonOk = gtk_button_new_with_label (_("Ok") );
917   gtk_signal_connect (GTK_OBJECT (ButtonOk), "clicked",
918                       GTK_SIGNAL_FUNC (GLOkPrefs),NULL);
919   gtk_box_pack_start (GTK_BOX (glButtonHBox), ButtonOk, TRUE, TRUE, 0);
920   (GTK_WIDGET_FLAGS (ButtonOk)  |= (GTK_CAN_DEFAULT));
921   gtk_widget_grab_default (ButtonOk);
922   gtk_widget_show (ButtonOk);
923 
924   /* Apply button                                                       */
925   ButtonApply = gtk_button_new_with_label (_("Apply") );
926   gtk_signal_connect (GTK_OBJECT (ButtonApply), "clicked",
927 		      GTK_SIGNAL_FUNC (GLApplyPrefs),NULL);
928   gtk_box_pack_start (GTK_BOX (glButtonHBox), ButtonApply, TRUE, TRUE, 0);
929   (GTK_WIDGET_FLAGS (ButtonApply)  |= (GTK_CAN_DEFAULT));
930   gtk_widget_grab_default (ButtonApply);
931   gtk_widget_show (ButtonApply);
932 
933   /* Cancel button                                                   */
934   ButtonCancel = gtk_button_new_with_label (_("Cancel") );
935   gtk_signal_connect (GTK_OBJECT (ButtonCancel), "clicked",
936                       GTK_SIGNAL_FUNC (GLDeletePrefs),
937 		      GTK_WIDGET (glPrefsWindow));
938   gtk_box_pack_start (GTK_BOX (glButtonHBox), ButtonCancel, TRUE, TRUE, 0);
939   (GTK_WIDGET_FLAGS (ButtonCancel)  |= (GTK_CAN_DEFAULT));
940   gtk_widget_grab_default (ButtonCancel);
941   gtk_widget_show (ButtonCancel);
942 
943   return;
944 
945 }
946 #endif /* OpenGL end */
947 
948