1 /****************************************************************************
2 
3   GLUI User Interface Toolkit (LGPL)
4   ---------------------------
5 
6      glui.cpp
7 
8           --------------------------------------------------
9 
10   Copyright (c) 1998 Paul Rademacher
11 
12   WWW:    http://sourceforge.net/projects/glui/
13   Forums: http://sourceforge.net/forum/?group_id=92496
14 
15   This library is free software; you can redistribute it and/or
16   modify it under the terms of the GNU Lesser General Public
17   License as published by the Free Software Foundation; either
18   version 2.1 of the License, or (at your option) any later version.
19 
20   This library is distributed in the hope that it will be useful,
21   but WITHOUT ANY WARRANTY; without even the implied warranty of
22   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
23   Lesser General Public License for more details.
24 
25   You should have received a copy of the GNU Lesser General Public
26   License along with this library; if not, write to the Free Software
27   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
28 
29 *****************************************************************************/
30 #include "glui_internal_control.h"
31 
32 
33 /**
34  Note: moving this routine here from glui_add_controls.cpp prevents the linker
35  from touching glui_add_controls.o in non-deprecated programs, which
36  descreases the linked size of small GLUI programs substantially (100K+). (OSL 2006/06)
37 */
add_child_to_control(GLUI_Node * parent,GLUI_Control * child)38 void GLUI_Node::add_child_to_control(GLUI_Node *parent,GLUI_Control *child)
39 {
40   GLUI_Control *parent_control;
41 
42   /*** Collapsible nodes have to be handled differently, b/c the first and
43     last children are swapped in and out  ***/
44   parent_control = ((GLUI_Control*)parent);
45   if ( parent_control->collapsible == true ) {
46     if ( NOT parent_control->is_open ) {
47       /** Swap in the original first and last children **/
48       parent_control->child_head  = parent_control->collapsed_node.child_head;
49       parent_control->child_tail  = parent_control->collapsed_node.child_tail;
50 
51       /*** Link this control ***/
52       child->link_this_to_parent_last( parent_control );
53 
54       /** Swap the children back out ***/
55       parent_control->collapsed_node.child_head = parent_control->child_head;
56       parent_control->collapsed_node.child_tail = parent_control->child_tail;
57       parent_control->child_head = NULL;
58       parent_control->child_tail = NULL;
59     }
60     else {
61       child->link_this_to_parent_last( parent_control );
62     }
63   }
64   else {
65     child->link_this_to_parent_last( parent_control );
66   }
67   child->glui = (GLUI*) parent_control->glui;
68   child->update_size();
69   child->enabled = parent_control->enabled;
70   child->glui->refresh();
71 
72   /** Now set the 'hidden' var based on the parent **/
73   if ( parent_control->hidden OR
74        (parent_control->collapsible AND NOT parent_control->is_open ) )
75   {
76     child->hidden = true;
77   }
78 }
79 
80 
81 /************************************ GLUI_Node::add_control() **************/
82 
add_control(GLUI_Control * child)83 int GLUI_Node::add_control( GLUI_Control *child )
84 {
85   add_child_to_control(this,child);
86   return true;
87 }
88 
89 /************************************ GLUI_Main::add_control() **************/
90 
add_control(GLUI_Node * parent,GLUI_Control * control)91 int GLUI_Main::add_control( GLUI_Node *parent, GLUI_Control *control )
92 {
93   add_child_to_control(parent,control);
94   return true;
95 }
96 
97 
98 
99 /*** This object must be used to create a GLUI ***/
100 
101 GLUI_Master_Object GLUI_Master;
102 
103 /************************************ finish_drawing() ***********
104   Probably a silly routine.  Called after all event handling callbacks.
105 */
106 
finish_drawing(void)107 static void finish_drawing(void)
108 {
109 	glFinish();
110 }
111 
112 /************************************ GLUI_CB::operator()() ************/
operator ()(GLUI_Control * ctrl) const113 void GLUI_CB::operator()(GLUI_Control*ctrl) const
114 {
115   if (idCB)  idCB(ctrl->user_id);
116   if (objCB) objCB(ctrl);
117 }
118 
119 
120 /************************************************ GLUI::GLUI() **********/
121 
init(const char * text,long flags,int x,int y,int parent_window)122 int GLUI::init( const char *text, long flags, int x, int y, int parent_window )
123 {
124   int old_glut_window;
125 
126   this->flags = flags;
127 
128   window_name = text;
129 
130   buffer_mode = buffer_back;  ///< New smooth way
131   //buffer_mode = buffer_front; ///< Old flickery way (a bit faster).
132 
133   /*** We copy over the current window callthroughs ***/
134   /*** (I think this might actually only be needed for subwindows) ***/
135   /*  glut_keyboard_CB = GLUI_Master.glut_keyboard_CB;
136       glut_reshape_CB  = GLUI_Master.glut_reshape_CB;
137       glut_special_CB  = GLUI_Master.glut_special_CB;
138       glut_mouse_CB    = GLUI_Master.glut_mouse_CB;*/
139 
140 
141   if ( (flags & GLUI_SUBWINDOW) != GLUI_SUBWINDOW ) {  /* not a subwindow, creating a new top-level window */
142     old_glut_window = glutGetWindow();
143 
144     create_standalone_window( window_name.c_str(), x, y );
145     setup_default_glut_callbacks();
146 
147     if ( old_glut_window > 0 )
148       glutSetWindow( old_glut_window );
149 
150     top_level_glut_window_id = glut_window_id;
151   }
152   else /* *is* a subwindow */
153   {
154     old_glut_window = glutGetWindow();
155 
156     create_subwindow( parent_window, flags );
157     setup_default_glut_callbacks();
158 
159     if ( old_glut_window > 0 )
160       glutSetWindow( old_glut_window );
161 
162     top_level_glut_window_id = parent_window;
163 
164     /*
165       glutReshapeFunc( glui_parent_window_reshape_func );
166       glutSpecialFunc( glui_parent_window_special_func );
167       glutKeyboardFunc( glui_parent_window_keyboard_func );
168       glutMouseFunc( glui_parent_window_mouse_func );
169       */
170 
171   }
172 
173   return true;
174 }
175 
176 
177 /**************************** GLUI_Main::create_standalone_window() ********/
178 
create_standalone_window(const char * name,int x,int y)179 void GLUI_Main::create_standalone_window( const char *name, int x, int y )
180 {
181   glutInitWindowSize( 100, 100 );
182   if ( x >= 0 OR y >= 0 )
183     glutInitWindowPosition( x, y );
184   glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE );
185   glut_window_id = glutCreateWindow( name );
186 }
187 
188 
189 /******************************** GLUI_Main::create_subwindow() **********/
190 
create_subwindow(int parent_window,int window_alignment)191 void GLUI_Main::create_subwindow( int parent_window, int window_alignment )
192 {
193   glut_window_id = glutCreateSubWindow(parent_window, 0,0, 100, 100);
194   this->parent_window = parent_window;
195 }
196 
197 
198 /**************************** GLUI_Main::setup_default_glut_callbacks() *****/
199 
setup_default_glut_callbacks(void)200 void GLUI_Main::setup_default_glut_callbacks( void )
201 {
202   glutDisplayFunc( glui_display_func );
203   glutReshapeFunc( glui_reshape_func );
204   glutKeyboardFunc( glui_keyboard_func );
205   glutSpecialFunc( glui_special_func );
206   glutMouseFunc( glui_mouse_func );
207   glutMotionFunc( glui_motion_func );
208   glutPassiveMotionFunc( glui_passive_motion_func );
209   glutEntryFunc( glui_entry_func );
210   glutVisibilityFunc( glui_visibility_func );
211   /*  glutIdleFunc( glui_idle_func );    // FIXME!  100% CPU usage!      */
212 }
213 
214 
215 /********************************************** glui_display_func() ********/
216 
glui_display_func(void)217 void glui_display_func(void)
218 {
219   GLUI *glui;
220 
221   /*  printf( "display func\n" );          */
222 
223   glui = GLUI_Master.find_glui_by_window_id( glutGetWindow() );
224 
225   if ( glui ) {
226     glui->display();
227     /*
228        Do not do anything after the above line, b/c the GLUI
229        window might have just closed itself
230    */
231   }
232 }
233 
234 
235 /********************************************** glui_reshape_func() ********/
236 
glui_reshape_func(int w,int h)237 void glui_reshape_func(int w,int h )
238 {
239   GLUI             *glui;
240   GLUI_Glut_Window *glut_window;
241   int               current_window;
242 
243   /*printf( "glui_reshape_func(): %d  w/h: %d/%d\n", glutGetWindow(), w, h );          */
244 
245   current_window = glutGetWindow();
246 
247   /***  First check if this is main glut window ***/
248   glut_window = GLUI_Master.find_glut_window( current_window );
249   if ( glut_window ) {
250     if (glut_window->glut_reshape_CB) glut_window->glut_reshape_CB(w,h);
251 
252     /***  Now send reshape events to all subwindows  ***/
253     glui = (GLUI*) GLUI_Master.gluis.first_child();
254     while(glui) {
255       if ( TEST_AND( glui->flags, GLUI_SUBWINDOW) AND
256 	   glui->parent_window == current_window ) {
257 	glutSetWindow( glui->get_glut_window_id());
258 	glui->reshape(w,h);
259 	/*	glui->check_subwindow_position();          */
260       }
261       glui = (GLUI*) glui->next();
262     }
263   }
264   else {
265     /***  A standalone GLUI window  ***/
266 
267     glui = GLUI_Master.find_glui_by_window_id( current_window );
268 
269     if ( glui ) {
270       glui->reshape(w,h);
271     }
272   }
273 }
274 
275 /********************************************** glui_keyboard_func() ********/
276 
glui_keyboard_func(unsigned char key,int x,int y)277 void glui_keyboard_func(unsigned char key, int x, int y)
278 {
279   GLUI              *glui;
280   int                current_window;
281   GLUI_Glut_Window  *glut_window;
282 
283   current_window = glutGetWindow();
284   glut_window = GLUI_Master.find_glut_window( current_window );
285 
286   /*printf( "key: %d\n", current_window );          */
287 
288   if ( glut_window ) { /**  Was event in a GLUT window?  **/
289     if ( GLUI_Master.active_control_glui AND GLUI_Master.active_control ) {
290       glutSetWindow( GLUI_Master.active_control_glui->get_glut_window_id() );
291 
292       GLUI_Master.active_control_glui->keyboard(key,x,y);
293 	  finish_drawing();
294 
295       glutSetWindow( current_window );
296     }
297     else {
298       if (glut_window->glut_keyboard_CB)
299         glut_window->glut_keyboard_CB( key, x, y );
300     }
301   }
302   else {   /***  Nope, event was in a standalone GLUI window  **/
303     glui = GLUI_Master.find_glui_by_window_id( glutGetWindow() );
304 
305     if ( glui ) {
306       glui->keyboard(key,x,y);
307 	  finish_drawing();
308     }
309   }
310 }
311 
312 
313 /************************************************ glui_special_func() ********/
314 
glui_special_func(int key,int x,int y)315 void glui_special_func(int key, int x, int y)
316 {
317   GLUI              *glui;
318   int                current_window;
319   GLUI_Glut_Window  *glut_window;
320 
321   current_window = glutGetWindow();
322   glut_window = GLUI_Master.find_glut_window( current_window );
323 
324   if (glut_window) /**  Was event in a GLUT window?  **/
325   {
326     if ( GLUI_Master.active_control_glui AND GLUI_Master.active_control )
327     {
328       glutSetWindow( GLUI_Master.active_control_glui->get_glut_window_id() );
329 
330       GLUI_Master.active_control_glui->special(key,x,y);
331       finish_drawing();
332 
333       glutSetWindow( current_window );
334     }
335     else
336     {
337       if (glut_window->glut_special_CB)
338         glut_window->glut_special_CB( key, x, y );
339     }
340   }
341   else /***  Nope, event was in a standalone GLUI window  **/
342   {
343     glui = GLUI_Master.find_glui_by_window_id(glutGetWindow());
344 
345     if ( glui )
346     {
347       glui->special(key,x,y);
348       finish_drawing();
349     }
350   }
351 }
352 
353 /********************************************** glui_mouse_func() ********/
354 
glui_mouse_func(int button,int state,int x,int y)355 void glui_mouse_func(int button, int state, int x, int y)
356 {
357   GLUI              *glui;
358   int                current_window;
359   GLUI_Glut_Window  *glut_window;
360 
361   current_window = glutGetWindow();
362   glut_window = GLUI_Master.find_glut_window( current_window );
363 
364   if ( glut_window ) { /**  Was event in a GLUT window?  **/
365     if ( GLUI_Master.active_control_glui != NULL )
366       GLUI_Master.active_control_glui->deactivate_current_control();
367 
368     if (glut_window->glut_mouse_CB)
369       glut_window->glut_mouse_CB( button, state, x, y );
370 	finish_drawing();
371   }
372   else {               /**  Nope - event was in a GLUI standalone window  **/
373     glui = GLUI_Master.find_glui_by_window_id( glutGetWindow() );
374     if ( glui ) {
375       glui->passive_motion( 0,0 );
376       glui->mouse( button, state, x, y );
377 	  finish_drawing();
378     }
379   }
380 }
381 
382 
383 /********************************************** glui_motion_func() ********/
384 
glui_motion_func(int x,int y)385 void glui_motion_func(int x, int y)
386 {
387   GLUI *glui;
388 
389   glui = GLUI_Master.find_glui_by_window_id( glutGetWindow() );
390 
391   if ( glui ) {
392     glui->motion(x,y);
393 	finish_drawing();
394   }
395 
396 }
397 
398 
399 /**************************************** glui_passive_motion_func() ********/
400 
glui_passive_motion_func(int x,int y)401 void glui_passive_motion_func(int x, int y)
402 {
403   GLUI *glui;
404 
405   glui = GLUI_Master.find_glui_by_window_id( glutGetWindow() );
406 
407   if ( glui ) {
408     glui->passive_motion(x,y);
409 	finish_drawing();
410   }
411 }
412 
413 
414 /********************************************** glui_entry_func() ********/
415 
glui_entry_func(int state)416 void glui_entry_func(int state)
417 {
418   GLUI *glui;
419 
420   glui = GLUI_Master.find_glui_by_window_id( glutGetWindow() );
421 
422   if ( glui ) {
423     glui->entry(state);
424   }
425 }
426 
427 
428 /******************************************** glui_visibility_func() ********/
429 
glui_visibility_func(int state)430 void glui_visibility_func(int state)
431 {
432   GLUI *glui;
433 
434   /*  printf( "IN GLUI VISIBILITY()\n" );          */
435   /*  fflush( stdout );          */
436 
437   glui = GLUI_Master.find_glui_by_window_id( glutGetWindow() );
438 
439   if ( glui ) {
440     glui->visibility(state);
441   }
442 }
443 
444 
445 /********************************************** glui_idle_func() ********/
446 /* Send idle event to each glui, then to the main window            */
447 
glui_idle_func(void)448 void glui_idle_func(void)
449 {
450   GLUI *glui;
451 
452   glui = (GLUI*) GLUI_Master.gluis.first_child();
453   while( glui ) {
454     glui->idle();
455 	finish_drawing();
456 
457     glui = (GLUI*) glui->next();
458   }
459 
460   if ( GLUI_Master.glut_idle_CB ) {
461     /*** We set the current glut window before calling the user's
462       idle function, even though glut explicitly says the window id is
463       undefined in an idle callback.  ***/
464 
465     /** Check what the current window is first ***/
466 
467     /*** Arbitrarily set the window id to the main gfx window of the
468       first glui window ***/
469     /*   int current_window, new_window;          */
470     /*   current_window = glutGetWindow();          */
471     /*   if (GLUI_Master.gluis.first_child() != NULL ) {          */
472     /*      new_window = ((GLUI_Main*)GLUI_Master.gluis.first_child())-> */
473     /*   main_gfx_window_id;          */
474     /*   if ( new_window > 0 AND new_window != old_window ) {          */
475     /*   --- Window is changed only if its not already the current window ---*/
476     /*  glutSetWindow( new_window );          */
477     /* }          */
478     /*}          */
479 
480     GLUI_Master.glut_idle_CB();
481   }
482 }
483 
484 /*********************************** GLUI_Master_Object::GLUI_Master_Object() ******/
485 
GLUI_Master_Object()486 GLUI_Master_Object::GLUI_Master_Object()
487 :	glui_id_counter(1),
488     glut_idle_CB(NULL)
489 {
490 }
491 
~GLUI_Master_Object()492 GLUI_Master_Object::~GLUI_Master_Object()
493 {
494 }
495 
496 /*********************************** GLUI_Master_Object::create_glui() ******/
497 
create_glui(const char * name,long flags,int x,int y)498 GLUI *GLUI_Master_Object::create_glui( const char *name, long flags,int x,int y )
499 {
500   GLUI *new_glui = new GLUI;
501   new_glui->init( name, flags, x, y, -1 );
502   new_glui->link_this_to_parent_last( &this->gluis );
503   return new_glui;
504 }
505 
506 
507 /************************** GLUI_Master_Object::create_glui_subwindow() ******/
508 
create_glui_subwindow(int parent_window,long flags)509 GLUI *GLUI_Master_Object::create_glui_subwindow( int parent_window,
510 						   long flags )
511 {
512   GLUI *new_glui = new GLUI;
513   GLUI_String new_name;
514   glui_format_str( new_name, "subwin_%p", this );
515 
516   new_glui->init( new_name.c_str(), flags | GLUI_SUBWINDOW, 0,0,
517 		    parent_window );
518   new_glui->main_panel->set_int_val( GLUI_PANEL_EMBOSSED );
519   new_glui->link_this_to_parent_last( &this->gluis );
520   return new_glui;
521 }
522 
523 
524 /********************** GLUI_Master_Object::find_glui_by_window_id() ********/
525 
find_glui_by_window_id(int window_id)526 GLUI  *GLUI_Master_Object::find_glui_by_window_id( int window_id )
527 {
528   GLUI_Node *node;
529 
530   node = gluis.first_child();
531   while( node ) {
532     if ( ((GLUI*)node)->get_glut_window_id() == window_id )
533       return (GLUI*) node;
534 
535     node = node->next();
536   }
537   return NULL;
538 }
539 
540 
541 /******************************************** GLUI_Main::display() **********/
542 
display(void)543 void    GLUI_Main::display( void )
544 {
545   int       win_w, win_h;
546 
547   /* SUBTLE: on freeGLUT, the correct window is always already set.
548   But older versions of GLUT need this call, or else subwindows
549   don't update properly when resizing or damage-painting.
550   */
551   glutSetWindow( glut_window_id );
552 
553   /* Set up OpenGL state for widget drawing */
554   glDisable( GL_DEPTH_TEST );
555   glCullFace( GL_BACK );
556   glDisable( GL_CULL_FACE );
557   glDisable( GL_LIGHTING );
558   set_current_draw_buffer();
559 
560   /**** This function is used as a special place to do 'safe' processing,
561     e.g., handling window close requests.
562     That is, we can't close the window directly in the callback, so
563     we set a flag, post a redisplay message (which eventually calls
564     this function), then close the window safely in here.  ****/
565   if ( closing ) {
566     close_internal();
567     return;
568   }
569 
570   /*  if ( TEST_AND( this->flags, GLUI_SUBWINDOW ))
571       check_subwindow_position();
572       */
573 
574   win_w = glutGet( GLUT_WINDOW_WIDTH );
575   win_h = glutGet( GLUT_WINDOW_HEIGHT );
576 
577   /*** Check here if the window needs resizing ***/
578   if ( win_w != main_panel->w OR win_h != main_panel->h ) {
579     glutReshapeWindow( main_panel->w, main_panel->h );
580     return;
581   }
582 
583   /*******    Draw GLUI window     ******/
584   glClearColor( (float) bkgd_color.r / 255.0,
585 		(float) bkgd_color.g / 255.0,
586 		(float) bkgd_color.b / 255.0,
587 		1.0 );
588   glClear( GL_COLOR_BUFFER_BIT ); /* | GL_DEPTH_BUFFER_BIT );          */
589 
590   set_ortho_projection();
591 
592   glMatrixMode( GL_MODELVIEW );
593   glLoadIdentity();
594 
595   /*** Rotate image so y increases downward.
596       In normal OpenGL, y increases upward. ***/
597   glTranslatef( (float) win_w/2.0, (float) win_h/2.0, 0.0 );
598   glRotatef( 180.0, 0.0, 1.0, 0.0 );
599   glRotatef( 180.0, 0.0, 0.0, 1.0 );
600   glTranslatef( (float) -win_w/2.0, (float) -win_h/2.0, 0.0 );
601 
602   // Recursively draw the main panel
603   //  main_panel->draw_bkgd_box( 0, 0, win_w, win_h );
604   main_panel->draw_recursive( 0, 0 );
605 
606   switch (buffer_mode) {
607   case buffer_front: /* Make sure drawing gets to screen */
608   	glFlush();
609 	break;
610   case buffer_back: /* Bring back buffer to front */
611   	glutSwapBuffers();
612 	break;
613   }
614 }
615 
616 
617 
618 
619 /*************************************** _glutBitmapWidthString() **********/
620 
_glutBitmapWidthString(void * font,const char * s)621 int _glutBitmapWidthString( void *font, const char *s )
622 {
623   const char *p = s;
624   int  width = 0;
625 
626   while( *p != '\0' )  {
627     width += glutBitmapWidth( font, *p );
628     p++;
629   }
630 
631   return width;
632 }
633 
634 /************************************ _glutBitmapString *********************/
635 /* Displays the contents of a string using GLUT's bitmap character function */
636 /* Does not handle newlines                                             */
637 
_glutBitmapString(void * font,const char * s)638 void _glutBitmapString( void *font, const char *s )
639 {
640   const char *p = s;
641 
642   while( *p != '\0' )  {
643     glutBitmapCharacter( font, *p );
644     p++;
645   }
646 }
647 
648 
649 
650 /****************************** GLUI_Main::reshape() **************/
651 
reshape(int reshape_w,int reshape_h)652 void    GLUI_Main::reshape( int reshape_w, int reshape_h )
653 {
654   int new_w, new_h;
655 
656   pack_controls();
657 
658   new_w = main_panel->w;/* + 1;          */
659   new_h = main_panel->h;/* + 1;          */
660 
661   if ( reshape_w != new_w OR reshape_h != new_h ) {
662     this->w = new_w;
663     this->h = new_h;
664 
665     glutReshapeWindow( new_w, new_h );
666   }
667   else {
668   }
669 
670   if ( TEST_AND( this->flags, GLUI_SUBWINDOW ) ) {
671     check_subwindow_position();
672 
673     /***** if ( TEST_AND(this->flags,GLUI_SUBWINDOW_LEFT )) {
674       }
675       else if ( TEST_AND(this->flags,GLUI_SUBWINDOW_LEFT )) {
676       }
677       else if ( TEST_AND(this->flags,GLUI_SUBWINDOW_LEFT )) {
678       }
679       else if ( TEST_AND(this->flags,GLUI_SUBWINDOW_RIGHT )) {
680       }
681       ****/
682   }
683 
684   glViewport( 0, 0, new_w, new_h );
685 
686   /*  printf( "%d: %d\n", glutGetWindow(), this->flags );          */
687 
688   glutPostRedisplay();
689 }
690 
691 
692 /****************************** GLUI_Main::keyboard() **************/
693 
keyboard(unsigned char key,int x,int y)694 void    GLUI_Main::keyboard(unsigned char key, int x, int y)
695 {
696   GLUI_Control *new_control;
697 
698   curr_modifiers = glutGetModifiers();
699 
700   /*** If it's a tab or shift tab, we don't pass it on to the controls.
701     Instead, we use it to cycle through active controls ***/
702   if ( key == '\t' AND !mouse_button_down AND
703        (!active_control || !active_control->wants_tabs())) {
704     if ( curr_modifiers & GLUT_ACTIVE_SHIFT ) {
705       new_control = find_prev_control( active_control );
706     }
707     else {
708       new_control = find_next_control( active_control );
709     }
710 
711     /*    if ( new_control )
712 	  printf( "new_control: %s\n", new_control->name );
713 	  */
714 
715     deactivate_current_control();
716     activate_control( new_control, GLUI_ACTIVATE_TAB );
717   }
718   else if ( key == ' ' AND active_control
719 	          AND active_control->spacebar_mouse_click ) {
720     /*** If the user presses the spacebar, and a non-edittext control
721       is active, we send it a mouse down event followed by a mouse up
722       event (simulated mouse-click) ***/
723 
724     active_control->mouse_down_handler( 0, 0 );
725     active_control->mouse_up_handler( 0, 0, true );
726   } else {
727     /*** Pass the keystroke onto the active control, if any ***/
728     if ( active_control != NULL )
729       active_control->key_handler( key, curr_modifiers );
730   }
731 }
732 
733 
734 /****************************** GLUI_Main::special() **************/
735 
special(int key,int x,int y)736 void    GLUI_Main::special(int key, int x, int y)
737 {
738   curr_modifiers = glutGetModifiers();
739 
740   /*** Pass the keystroke onto the active control, if any ***/
741   if ( active_control != NULL )
742     active_control->special_handler( key, glutGetModifiers() );
743 }
744 
745 
746 
747 /****************************** GLUI_Main::mouse() **************/
748 
mouse(int button,int state,int x,int y)749 void    GLUI_Main::mouse(int button, int state, int x, int y)
750 {
751   int callthrough;
752   GLUI_Control *control;
753 
754   /*  printf( "MOUSE: %d %d\n", button, state );          */
755 
756   callthrough = true;
757 
758   curr_modifiers = glutGetModifiers();
759 
760   if ( button == GLUT_LEFT ) {
761     control = find_control( x, y );
762 
763     /*if ( control ) printf( "control: %s\n", control->name.c_str() );      */
764 
765     if ( mouse_button_down AND active_control != NULL AND
766       	 state == GLUT_UP )
767     {
768       /** We just released the mouse, which was depressed at some control **/
769 
770       callthrough = active_control->
771         mouse_up_handler( x, y, control==active_control);
772       glutSetCursor( GLUT_CURSOR_LEFT_ARROW );
773 
774       if ( active_control AND
775            active_control->active_type == GLUI_CONTROL_ACTIVE_MOUSEDOWN AND 0)
776       {
777         /*** This is a control that needs to be deactivated when the
778         mouse button is released ****/
779         deactivate_current_control();
780       }
781     }
782     else {
783       if ( control ) {
784         if ( NOT mouse_button_down AND state == GLUT_DOWN ) {
785           /*** We just pressed the mouse down at some control ***/
786 
787           if ( active_control != control ) {
788             if ( active_control != NULL ) {
789               /** There is an active control still - deactivate it ***/
790               deactivate_current_control();
791             }
792           }
793 
794           if ( control->enabled ) {
795             activate_control( control, GLUI_ACTIVATE_MOUSE );
796             callthrough    = control->mouse_down_handler( x, y );
797           }
798         }
799       }
800     }
801 
802     if ( state == GLUT_DOWN )
803       mouse_button_down = true;
804     else if ( state == GLUT_UP )
805       mouse_button_down = false;
806   }
807 
808   /**
809     NO CALLTHROUGH NEEDED FOR MOUSE EVENTS
810     if ( callthrough AND glut_mouse_CB )
811     glut_mouse_CB( button, state, x, y );
812     **/
813 
814   callthrough=callthrough; /* To get rid of compiler warnings */
815 }
816 
817 
818 /****************************** GLUI_Main::motion() **************/
819 
motion(int x,int y)820 void    GLUI_Main::motion(int x, int y)
821 {
822   int           callthrough;
823   GLUI_Control *control;
824 
825   /*  printf( "MOTION: %d %d\n", x, y );          */
826 
827   callthrough = true;
828 
829   control = find_control(x,y);
830 
831   if ( mouse_button_down AND active_control != NULL ) {
832     callthrough =
833       active_control->mouse_held_down_handler(x,y,control==active_control);
834   }
835 
836   /**
837     NO CALLTHROUGH NEEDED FOR MOUSE EVENTS
838 
839     if ( callthrough AND glut_motion_CB )
840     glut_motion_CB(x,y);
841     **/
842 
843   callthrough=callthrough; /* To get rid of compiler warnings */
844 }
845 
846 
847 /*********************** GLUI_Main::passive_motion() **************/
848 
passive_motion(int x,int y)849 void    GLUI_Main::passive_motion(int x, int y)
850 {
851   GLUI_Control *control;
852 
853   control = find_control( x, y );
854 
855   /*  printf( "%p %p\n", control, mouse_over_control );          */
856 
857   if ( control != mouse_over_control ) {
858     if ( mouse_over_control ) {
859       mouse_over_control->mouse_over( false, x, y );
860     }
861 
862     if ( control ) {
863       control->mouse_over( true, x, y );
864       mouse_over_control = control;
865     }
866   }
867 
868   /*
869     if ( curr_cursor != GLUT_CURSOR_INHERIT ) {
870     curr_cursor = GLUT_CURSOR_INHERIT;
871     glutSetCursor( GLUT_CURSOR_INHERIT );
872     }*/
873 
874 }
875 
876 
877 /****************************** GLUI_Main::entry() **************/
878 
entry(int state)879 void    GLUI_Main::entry(int state)
880 {
881   /*if ( NOT active_control OR ( active_control AND ( active_control->type == GLUI_CONTROL_EDITTEXT
882     OR active_control->type == GLUI_CONTROL_SPINNER) ) )*/
883   glutSetCursor( GLUT_CURSOR_LEFT_ARROW );
884 }
885 
886 
887 /****************************** GLUI_Main::visibility() **************/
888 
visibility(int state)889 void    GLUI_Main::visibility(int state)
890 {
891 }
892 
893 
894 /****************************** GLUI_Main::idle() **************/
895 
idle(void)896 void    GLUI_Main::idle(void)
897 {
898   /*** Pass the idle event onto the active control, if any ***/
899 
900   /*  printf( "IDLE \t" );          */
901 
902   if ( active_control != NULL ) {
903     /* First we check if the control actually needs the idle right now.
904        Otherwise, let's avoid wasting cycles and OpenGL context switching */
905 
906     if ( active_control->needs_idle() ) {
907       /*** Set the current glut window to the glui window */
908       /*** But don't change the window if we're already at that window ***/
909 
910       if ( glut_window_id > 0 AND glutGetWindow() != glut_window_id ) {
911 	glutSetWindow( glut_window_id );
912       }
913 
914       active_control->idle();
915     }
916   }
917 }
918 
needs_idle(void)919 int  GLUI_Main::needs_idle( void )
920 {
921   return active_control != NULL && active_control->needs_idle();
922 }
923 
924 
925 /******************************************* GLUI_Main::find_control() ******/
926 
find_control(int x,int y)927 GLUI_Control  *GLUI_Main::find_control( int x, int y )
928 {
929   GLUI_Control *node, *last_container;
930 
931   last_container = NULL;
932 
933   node = main_panel;
934   while( node != NULL ) {
935     if ( !dynamic_cast<GLUI_Column*>(node) AND
936          PT_IN_BOX( x, y,
937                     node->x_abs, node->x_abs + node->w,
938                     node->y_abs, node->y_abs + node->h )
939          )
940     {
941       /*** Point is inside current node ***/
942 
943       if ( node->first_child() == NULL ) {
944         /*** SPECIAL CASE: for edittext boxes, we make sure click is
945              in box, and not on name string.  This should be generalized
946              for all controls later... ***/
947         if ( dynamic_cast<GLUI_EditText*>(node) ) {
948           if ( x < node->x_abs + ((GLUI_EditText*)node)->text_x_offset )
949             return (GLUI_Control*) node->parent();
950         }
951 
952         return node;   /* point is inside this node, and node has no children,
953                           so return this node as the selected node */
954       }
955       else {
956         /*** This is a container class ***/
957         last_container = node;
958         node = (GLUI_Control*) node->first_child();  /* Descend into child */
959       }
960 
961     }
962     else {
963       node = (GLUI_Control*) node->next();
964     }
965   }
966 
967   /** No leaf-level nodes found to accept the mouse click, so
968       return the last container control found which DOES accept the click **/
969 
970   if ( last_container ) {
971     /*    printf( "ctrl: '%s'\n", last_container->name );          */
972 
973     return last_container;
974   }
975   else {
976     return NULL;
977   }
978 }
979 
980 
981 /************************************* GLUI_Main::pack_controls() ***********/
982 
pack_controls(void)983 void      GLUI_Main::pack_controls( void )
984 {
985   main_panel->pack(0,0);
986 
987   /**** Now align controls within their bounds ****/
988   align_controls( main_panel );
989 
990   /***  If this is a subwindow, expand panel to fit parent window  ***/
991   if ( TEST_AND( this->flags, GLUI_SUBWINDOW ) ) {
992     int parent_h, parent_w;
993     int orig_window;
994 
995     orig_window = glutGetWindow();
996     glutSetWindow( this->top_level_glut_window_id );
997     parent_h = glutGet( GLUT_WINDOW_HEIGHT );
998     parent_w = glutGet( GLUT_WINDOW_WIDTH );
999 
1000     glutSetWindow( orig_window );
1001 
1002     /*		printf( "%d %d\n", parent_h, parent_w );          */
1003 
1004     if ( 1 ) {
1005       if ( TEST_AND(this->flags,GLUI_SUBWINDOW_TOP )) {
1006 	main_panel->w = MAX( main_panel->w, parent_w );
1007       }
1008       else if ( TEST_AND(this->flags,GLUI_SUBWINDOW_LEFT )) {
1009 	main_panel->h = MAX( main_panel->h, parent_h );
1010       }
1011       else if ( TEST_AND(this->flags,GLUI_SUBWINDOW_BOTTOM )) {
1012 	main_panel->w = MAX( main_panel->w, parent_w );
1013       }
1014       else if ( TEST_AND(this->flags,GLUI_SUBWINDOW_RIGHT )) {
1015 	main_panel->h = MAX( main_panel->h, parent_h );
1016       }
1017     }
1018   }
1019 
1020   this->w = main_panel->w;
1021   this->h = main_panel->h;
1022 }
1023 
1024 
1025 /************************************ GLUI_Main::align_controls() **********/
1026 
align_controls(GLUI_Control * control)1027 void    GLUI_Main::align_controls( GLUI_Control *control )
1028 {
1029   GLUI_Control *child;
1030 
1031   control->align();
1032 
1033   child = (GLUI_Control*) control->first_child();
1034 
1035   while( child != NULL ) {
1036     align_controls( child );
1037 
1038     child = (GLUI_Control*)child->next();
1039   }
1040 }
1041 
1042 
1043 
1044 /*********************************** GLUI::set_main_gfx_window() ************/
1045 
set_main_gfx_window(int window_id)1046 void   GLUI::set_main_gfx_window( int window_id )
1047 {
1048   main_gfx_window_id = window_id;
1049 }
1050 
1051 
1052 /********************************* GLUI_Main::post_update_main_gfx() ********/
1053 
post_update_main_gfx(void)1054 void   GLUI_Main::post_update_main_gfx( void )
1055 {
1056   int old_window;
1057 
1058   if ( main_gfx_window_id > 0 ) {
1059     old_window = glutGetWindow();
1060     glutSetWindow( main_gfx_window_id );
1061     glutPostRedisplay();
1062     if( old_window > 0 )
1063       glutSetWindow( old_window );
1064   }
1065 }
1066 
1067 /********************************* GLUI_Main::should_redraw_now() ********/
1068 /** Return true if this control should redraw itself immediately (front buffer);
1069    Or queue up a redraw and return false if it shouldn't (back buffer).
1070 
1071    Called from GLUI_Control::redraw.
1072 */
should_redraw_now(GLUI_Control * ctl)1073 bool	     GLUI_Main::should_redraw_now(GLUI_Control *ctl)
1074 {
1075   switch (buffer_mode) {
1076   case buffer_front: return true; /* always draw in front-buffer mode */
1077   case buffer_back: {
1078     int orig = ctl->set_to_glut_window();
1079     glutPostRedisplay(); /* redraw soon */
1080     ctl->restore_window(orig);
1081     return false; /* don't draw now. */
1082    }
1083   }
1084   return false; /* never executed */
1085 }
1086 
1087 /********************************* GLUI_Main::set_current_draw_buffer() ********/
1088 
set_current_draw_buffer(void)1089 int          GLUI_Main::set_current_draw_buffer( void )
1090 {
1091   /* Save old buffer */
1092   GLint state;
1093   glGetIntegerv( GL_DRAW_BUFFER, &state );
1094   /* Switch to new buffer */
1095   switch (buffer_mode) {
1096   case buffer_front: glDrawBuffer(GL_FRONT); break;
1097   case buffer_back:  glDrawBuffer(GL_BACK);  break; /* might not be needed... */
1098   }
1099   return (int)state;
1100 }
1101 
1102 
1103 /********************************* GLUI_Main::restore_draw_buffer() **********/
1104 
restore_draw_buffer(int buffer_state)1105 void         GLUI_Main::restore_draw_buffer( int buffer_state )
1106 {
1107   glDrawBuffer( buffer_state );
1108 }
1109 
1110 
1111 /******************************************** GLUI_Main::GLUI_Main() ********/
1112 
GLUI_Main(void)1113 GLUI_Main::GLUI_Main( void )
1114 {
1115   mouse_button_down       = false;
1116   w                       = 0;
1117   h                       = 0;
1118   active_control          = NULL;
1119   mouse_over_control      = NULL;
1120   main_gfx_window_id      = -1;
1121   glut_window_id          = -1;
1122   curr_modifiers          = 0;
1123   closing                 = false;
1124   parent_window           = -1;
1125   glui_id                 = GLUI_Master.glui_id_counter;
1126   GLUI_Master.glui_id_counter++;
1127 
1128   font                    = GLUT_BITMAP_HELVETICA_12;
1129   curr_cursor             = GLUT_CURSOR_LEFT_ARROW;
1130 
1131   int r=200, g=200, b=200;
1132   bkgd_color.set( r,g,b );
1133   bkgd_color_f[0] = r / 255.0;
1134   bkgd_color_f[1] = g / 255.0;
1135   bkgd_color_f[2] = b / 255.0;
1136 
1137   /*** Create the main panel ***/
1138   main_panel              = new GLUI_Panel;
1139   main_panel->set_int_val( GLUI_PANEL_NONE );
1140   main_panel->glui        = (GLUI*) this;
1141   main_panel->name        = "\0";
1142 }
1143 
1144 /************************************ GLUI_Main::draw_raised_box() **********/
1145 
draw_raised_box(int x,int y,int w,int h)1146 void      GLUI_Main::draw_raised_box( int x, int y, int w, int h )
1147 {
1148   w = w+x;
1149   h = h+y;
1150 
1151   glColor3ub( bkgd_color.r, bkgd_color.g, bkgd_color.b );
1152   glBegin( GL_LINE_LOOP );
1153   glVertex2i( x+1, y+1 );  glVertex2i( w-1, y+1 );
1154   glVertex2i( w-1, h-1 );  glVertex2i( x+1, h-1 );
1155   glEnd();
1156 
1157   glColor3d( 1.0, 1.0, 1.0 );
1158   glBegin( GL_LINE_STRIP );
1159   glVertex2i( x, h );  glVertex2i( x, y );  glVertex2i( w, y );
1160   glEnd();
1161 
1162   glColor3d( 0.0, 0.0, 0.0 );
1163   glBegin( GL_LINE_STRIP );
1164   glVertex2i( w, y );  glVertex2i( w, h );  glVertex2i( x, h );
1165   glEnd();
1166 
1167   glColor3d( .5, .5, .5 );
1168   glBegin( GL_LINE_STRIP );
1169   glVertex2i( w-1, y+1 );  glVertex2i( w-1, h-1 );  glVertex2i( x+1, h-1 );
1170   glEnd();
1171 }
1172 
1173 
1174 /************************************ GLUI_Main::draw_lowered_box() **********/
1175 /* Not quite perfect...      **/
1176 
draw_lowered_box(int x,int y,int w,int h)1177 void      GLUI_Main::draw_lowered_box( int x, int y, int w, int h )
1178 {
1179   w = w+x;
1180   h = h+y;
1181 
1182   glColor3ub( bkgd_color.r, bkgd_color.g, bkgd_color.b );
1183   glBegin( GL_LINE_LOOP );
1184   glVertex2i( x+1, y+1 );         glVertex2i( w-1, y+1 );
1185   glVertex2i( w-1, h-1 );     glVertex2i( x+1, h-1 );
1186   glEnd();
1187 
1188   glColor3d( 0.0, 0.0, 0.0 );
1189   glBegin( GL_LINE_STRIP );
1190   glVertex2i( x, h );  glVertex2i( x, y );  glVertex2i( w, y );
1191   glEnd();
1192 
1193   glColor3d( 1.0, 1.0, 1.0 );
1194   glBegin( GL_LINE_STRIP );
1195   glVertex2i( w, y );  glVertex2i( w, h );  glVertex2i( x, h );
1196   glEnd();
1197 
1198   glColor3d( .5, .5, .5 );
1199   glBegin( GL_LINE_STRIP );
1200   glVertex2i( w-1, y+1 );  glVertex2i( w-1, h-1 );  glVertex2i( x+1, h-1 );
1201   glEnd();
1202 }
1203 
1204 
1205 /************************************* GLUI_Main::activate_control() *********/
1206 
activate_control(GLUI_Control * control,int how)1207 void         GLUI_Main::activate_control( GLUI_Control *control, int how )
1208 {
1209   /** Are we not activating a control in the same window as the
1210     previous active control? */
1211   if ( GLUI_Master.active_control_glui AND
1212        this != (GLUI_Main*) GLUI_Master.active_control_glui ) {
1213     GLUI_Master.active_control_glui->deactivate_current_control();
1214   }
1215 
1216   /*******      Now activate it      *****/
1217   if ( control != NULL AND control->can_activate AND control->enabled ) {
1218     active_control = control;
1219 
1220     control->activate(how);
1221 
1222     /*if ( NOT active_control->is_container OR           */
1223     /*		active_control->type == GLUI_CONTROL_ROLLOUT) {          */
1224     active_control->redraw();
1225     /*}          */
1226   }
1227   else {
1228     active_control = NULL;
1229   }
1230 
1231   /*  printf( "activate: %d\n", glutGetWindow() );          */
1232   GLUI_Master.active_control      = active_control;
1233   GLUI_Master.active_control_glui = (GLUI*) this;
1234 }
1235 
1236 
1237 /************************* GLUI_Main::deactivate_current_control() **********/
1238 
deactivate_current_control(void)1239 void         GLUI_Main::deactivate_current_control( void )
1240 {
1241   int orig;
1242 
1243   if ( active_control != NULL ) {
1244     orig = active_control->set_to_glut_window();
1245 
1246     active_control->deactivate();
1247 
1248     /** If this isn't a container control, then redraw it in its
1249       deactivated state.  Container controls, such as panels, look
1250       the same activated or not **/
1251 
1252     /*if ( NOT active_control->is_container OR           */
1253     /*		active_control->type == GLUI_CONTROL_ROLLOUT ) {        */
1254     active_control->redraw();
1255     /*}          */
1256 
1257     active_control->restore_window( orig );
1258 
1259     active_control = NULL;
1260   }
1261 
1262   /*  printf( "deactivate: %d\n", glutGetWindow() );          */
1263   GLUI_Master.active_control      = NULL;
1264   GLUI_Master.active_control_glui = NULL;
1265 }
1266 
1267 
1268 /****************************** GLUI_Main::find_next_control() **************/
1269 
find_next_control_(GLUI_Control * control)1270 GLUI_Control  *GLUI_Main::find_next_control_( GLUI_Control *control )
1271 {
1272   /*** THIS IS NOT find_next_control()!  This is an unused older
1273     version (look at the underscore at the end) ***/
1274 
1275   if ( control == NULL )
1276     return find_next_control_rec( main_panel );
1277   else
1278     return find_next_control_rec( control );
1279 }
1280 
1281 /****************************** GLUI_Main::find_next_control() **************/
1282 
find_next_control_rec(GLUI_Control * control)1283 GLUI_Control  *GLUI_Main::find_next_control_rec( GLUI_Control *control )
1284 {
1285   GLUI_Control *child = NULL, *rec_control, *sibling;
1286 
1287   /*** Recursively investigate children ***/
1288   child = (GLUI_Control*) control->first_child();
1289   if ( child ) {
1290     /*** If we can activate the first child, then do so ***/
1291     if ( child->can_activate AND child->enabled )
1292       return child;
1293     else     /*** Recurse into first child ***/
1294       rec_control = find_next_control_rec( child );
1295 
1296     if ( rec_control )
1297       return rec_control;
1298   }
1299 
1300   /*** At this point, either we don't have children, or the child cannot
1301     be activated.  So let's try the next sibling ***/
1302 
1303   sibling = (GLUI_Control*) control->next();
1304   if ( sibling ) {
1305     if ( sibling->can_activate AND sibling->enabled )
1306       return sibling;
1307     else     /*** Recurse into sibling ***/
1308       rec_control = find_next_control_rec( sibling );
1309 
1310     if ( rec_control )
1311       return rec_control;
1312   }
1313 
1314   return NULL;
1315 }
1316 
1317 
1318 /****************************** GLUI_Main::find_next_control() **************/
1319 
find_next_control(GLUI_Control * control)1320 GLUI_Control  *GLUI_Main::find_next_control( GLUI_Control *control )
1321 {
1322   GLUI_Control *tmp_control = NULL;
1323   int           back_up;
1324 
1325   if ( control == NULL )
1326     control = main_panel;
1327 
1328   while( control != NULL ) {
1329     /** see if this control has a child **/
1330     tmp_control = (GLUI_Control*) control->first_child();
1331 
1332     if ( tmp_control != NULL ) {
1333       if ( tmp_control->can_activate AND tmp_control->enabled )
1334 	return tmp_control;
1335 
1336       control = tmp_control;  /* Descend into child */
1337       continue;
1338     }
1339 
1340     /*** At this point, control has no children ***/
1341 
1342     /** see if this control has a next sibling **/
1343     tmp_control = (GLUI_Control*) control->next();
1344 
1345     if ( tmp_control != NULL ) {
1346       if ( tmp_control->can_activate AND tmp_control->enabled )
1347 	return tmp_control;
1348 
1349       control = tmp_control;
1350       continue;
1351     }
1352 
1353     /** back up until we find a sibling of an ancestor **/
1354     back_up = true;
1355     while ( control->parent() AND back_up ) {
1356       control = (GLUI_Control*) control->parent();
1357 
1358       if ( control->next() ) {
1359 	control = (GLUI_Control*) control->next();
1360 	if ( control->can_activate AND control->enabled )
1361 	  return control;
1362 	else
1363 	  back_up = false;
1364 
1365 	/***	if ( control->is_container ) {
1366 	  tmp_control = control;
1367 	  control     = NULL;
1368 	  break;
1369 	  }
1370 	  else {
1371 	  back_up = false;
1372 	  }
1373 	  ***/
1374       }
1375     }
1376 
1377     /** Check if we've cycled back to the top... if so, return NULL **/
1378     if ( control == main_panel ) {
1379       return NULL;
1380     }
1381   }
1382   /*
1383     if ( tmp_control != NULL AND tmp_control->can_activate AND
1384     tmp_control->enabled ) {
1385     return tmp_control;
1386     }*/
1387 
1388   return NULL;
1389 }
1390 
1391 
1392 /****************************** GLUI_Main::find_prev_control() **************/
1393 
find_prev_control(GLUI_Control * control)1394 GLUI_Control  *GLUI_Main::find_prev_control( GLUI_Control *control )
1395 {
1396   GLUI_Control *tmp_control, *next_control;
1397 
1398   if ( control == NULL ) {        /* here we find the last valid control */
1399     next_control = main_panel;
1400 
1401     do {
1402       tmp_control  = next_control;
1403       next_control = find_next_control( tmp_control );
1404     } while( next_control != NULL );
1405 
1406     return tmp_control;
1407   }
1408   else {                         /* here we find the actual previous control */
1409     next_control = main_panel;
1410 
1411     do {
1412       tmp_control  = next_control;
1413       next_control = find_next_control( tmp_control );
1414     } while( next_control != NULL AND next_control != control );
1415 
1416     if ( next_control == NULL OR tmp_control == main_panel )
1417       return NULL;
1418     else
1419       return tmp_control;
1420   }
1421 }
1422 
1423 /************************* GLUI_Master_Object::set_glutIdleFunc() ***********/
1424 
set_glutIdleFunc(void (* f)(void))1425 void    GLUI_Master_Object::set_glutIdleFunc(void (*f)(void))
1426 {
1427   glut_idle_CB = f;
1428   GLUI_Master.glui_setIdleFuncIfNecessary();
1429 }
1430 
1431 
1432 /**************************************** GLUI::disable() ********************/
1433 
disable(void)1434 void   GLUI::disable( void )
1435 {
1436   deactivate_current_control();
1437   main_panel->disable();
1438 }
1439 
1440 
1441 /******************************************** GLUI::sync_live() **************/
1442 
sync_live(void)1443 void   GLUI::sync_live( void )
1444 {
1445   main_panel->sync_live(true, true);
1446 }
1447 
1448 
1449 /********************************* GLUI_Master_Object::sync_live_all() *****/
1450 
sync_live_all(void)1451 void   GLUI_Master_Object::sync_live_all( void )
1452 {
1453   GLUI *glui;
1454 
1455   glui = (GLUI*) GLUI_Master.gluis.first_child();
1456   while( glui ) {
1457 
1458     glui->sync_live();  /** sync it **/
1459 
1460     glui = (GLUI*) glui->next();
1461   }
1462 }
1463 
1464 
1465 /************************************* GLUI_Master_Object::close() **********/
1466 
close_all(void)1467 void   GLUI_Master_Object::close_all( void )
1468 {
1469   GLUI *glui;
1470 
1471   glui = (GLUI*) GLUI_Master.gluis.first_child();
1472   while( glui ) {
1473 
1474     glui->close();  /** Set flag to close **/
1475 
1476     glui = (GLUI*) glui->next();
1477   }
1478 }
1479 
1480 
1481 /************************************* GLUI_Main::close_internal() **********/
1482 
close_internal(void)1483 void   GLUI_Main::close_internal( void )
1484 {
1485   glutDestroyWindow(glutGetWindow()); /** Close this window **/
1486 
1487   this->unlink();
1488 
1489   if ( GLUI_Master.active_control_glui == this ) {
1490     GLUI_Master.active_control      = NULL;
1491     GLUI_Master.active_control_glui = NULL;
1492   }
1493 
1494   if ( parent_window != -1 ) {
1495     glutSetWindow( parent_window );
1496     int win_w = glutGet( GLUT_WINDOW_WIDTH );
1497     int win_h = glutGet( GLUT_WINDOW_HEIGHT );
1498     glutReshapeWindow(win_w+1, win_h);
1499     glutReshapeWindow(win_w-1, win_h);
1500   }
1501 
1502   delete this->main_panel;
1503 
1504   delete this;
1505 }
1506 
1507 
1508 /************************************************** GLUI::close() **********/
1509 
close(void)1510 void   GLUI::close( void )
1511 {
1512   int   old_glut_window;
1513 
1514   closing = true;
1515 
1516   old_glut_window = glutGetWindow();
1517   glutSetWindow( get_glut_window_id() );
1518   glutPostRedisplay();
1519 
1520   glutSetWindow( old_glut_window );
1521 }
1522 
1523 
1524 /************************** GLUI_Main::check_subwindow_position() **********/
1525 
check_subwindow_position(void)1526 void   GLUI_Main::check_subwindow_position( void )
1527 {
1528   /*** Reposition this window if subwindow ***/
1529   if ( TEST_AND( this->flags, GLUI_SUBWINDOW ) ) {
1530 
1531     int parent_w, parent_h, new_x, new_y;
1532     int old_window = glutGetWindow();
1533 
1534     glutSetWindow( glut_window_id );
1535 
1536     glutSetWindow( glutGet( GLUT_WINDOW_PARENT ));
1537     parent_w = glutGet( GLUT_WINDOW_WIDTH );
1538     parent_h = glutGet( GLUT_WINDOW_HEIGHT );
1539 
1540     glutSetWindow( glut_window_id );
1541 
1542     if ( TEST_AND(this->flags,GLUI_SUBWINDOW_RIGHT )) {
1543       new_x = parent_w - this->w;
1544       new_y = 0;
1545     }
1546     else if ( TEST_AND(this->flags,GLUI_SUBWINDOW_LEFT )) {
1547       new_x = 0;
1548       new_y = 0;
1549     }
1550     else if ( TEST_AND(this->flags,GLUI_SUBWINDOW_BOTTOM )) {
1551       new_x = 0;
1552       new_y = parent_h - this->h;
1553     }
1554     else {    /***   GLUI_SUBWINDOW_TOP    ***/
1555       new_x = 0;
1556       new_y = 0;
1557     }
1558 
1559     /** Now make adjustments based on presence of other subwindows **/
1560     GLUI *curr_glui;
1561     curr_glui = (GLUI*) GLUI_Master.gluis.first_child();
1562     while( curr_glui ) {
1563       if ( TEST_AND( curr_glui->flags, GLUI_SUBWINDOW) AND
1564 	   curr_glui->parent_window == this->parent_window ) {
1565 
1566 	if ( TEST_AND( curr_glui->flags,GLUI_SUBWINDOW_LEFT ) ) {
1567 	}
1568 	else if ( TEST_AND( curr_glui->flags,GLUI_SUBWINDOW_BOTTOM ) ) {
1569 	}
1570 	else if ( TEST_AND( curr_glui->flags,GLUI_SUBWINDOW_RIGHT ) ) {
1571 	}
1572 	else if ( TEST_AND( curr_glui->flags,GLUI_SUBWINDOW_TOP ) AND
1573 		  ( TEST_AND( this->flags,GLUI_SUBWINDOW_LEFT ) OR
1574 		    TEST_AND( this->flags,GLUI_SUBWINDOW_RIGHT ) ) ) {
1575 	  /** If we are a RIGHT or LEFT subwindow, and there exists some
1576 	    TOP subwindow, bump our position down  **/
1577 
1578 	  new_y += curr_glui->h;
1579 	}
1580 
1581 	/** CHeck multiple subwins at same position  **/
1582 	/** We check the glui_id's:  only the glui with the higher
1583 	  ID number (meaning it was created later) gets bumped over **/
1584 	if ( curr_glui != this AND this->glui_id > curr_glui->glui_id ) {
1585 	  if ( TEST_AND( this->flags,GLUI_SUBWINDOW_LEFT ) AND
1586 	       TEST_AND( curr_glui->flags,GLUI_SUBWINDOW_LEFT ) ) {
1587 	    new_x += curr_glui->w;
1588 	  }
1589 	  else if ( TEST_AND( this->flags,GLUI_SUBWINDOW_TOP ) AND
1590 		    TEST_AND( curr_glui->flags,GLUI_SUBWINDOW_TOP ) ) {
1591 	    new_y += curr_glui->h;
1592 	  }
1593 	  else if ( TEST_AND( this->flags,GLUI_SUBWINDOW_BOTTOM ) AND
1594 		    TEST_AND( curr_glui->flags,GLUI_SUBWINDOW_BOTTOM ) ) {
1595 	    new_y -= curr_glui->h;
1596 	  }
1597 	  else if ( TEST_AND( this->flags,GLUI_SUBWINDOW_RIGHT ) AND
1598 		    TEST_AND( curr_glui->flags,GLUI_SUBWINDOW_RIGHT ) ) {
1599 	    new_x -= curr_glui->w;
1600 	  }
1601 
1602 	}
1603       }
1604 
1605       curr_glui = (GLUI*) curr_glui->next();
1606     }
1607 
1608 
1609 
1610     CLAMP( new_x, 0, new_x );
1611     CLAMP( new_y, 0, new_y );
1612 
1613     glutPositionWindow( new_x, new_y );
1614     /*		glutPostRedisplay();          */
1615 
1616     glutSetWindow( old_window );
1617   }
1618 }
1619 
1620 
1621 /********************************* GLUI_Master_Object::reshape() **********/
1622 /* This gets called by the user from a GLUT reshape callback.  So we look */
1623 /* for subwindows that belong to the current window                   */
1624 
reshape(void)1625 void  GLUI_Master_Object::reshape( void )
1626 {
1627   GLUI *glui;
1628   int   current_window;
1629 
1630   current_window = glutGetWindow();
1631 
1632   glui = (GLUI*) GLUI_Master.gluis.first_child();
1633   while( glui ) {
1634     if ( TEST_AND( glui->flags, GLUI_SUBWINDOW) AND
1635 	 glui->parent_window == current_window ) {
1636       glutSetWindow( glui->get_glut_window_id());
1637       glui->check_subwindow_position();
1638     }
1639 
1640     glui = (GLUI*) glui->next();
1641   }
1642 
1643   glutSetWindow(current_window);
1644 }
1645 
1646 
1647 /**************************** GLUI_Master_Object::set_glutReshapeFunc() *****/
1648 
set_glutReshapeFunc(void (* f)(int width,int height))1649 void GLUI_Master_Object::set_glutReshapeFunc(void (*f)(int width, int height))
1650 {
1651   glutReshapeFunc( glui_reshape_func );
1652   add_cb_to_glut_window( glutGetWindow(), GLUI_GLUT_RESHAPE, (void*) f);
1653 }
1654 
1655 
1656 /**************************** GLUI_Master_Object::set_glutKeyboardFunc() ****/
1657 
set_glutKeyboardFunc(void (* f)(unsigned char key,int x,int y))1658 void GLUI_Master_Object::set_glutKeyboardFunc(void (*f)(unsigned char key,
1659 							int x, int y))
1660 {
1661   glutKeyboardFunc( glui_keyboard_func );
1662   add_cb_to_glut_window( glutGetWindow(), GLUI_GLUT_KEYBOARD, (void*) f);
1663 }
1664 
1665 
1666 /*********************** GLUI_Master_Object::set_glutSpecialFunc() **********/
1667 
set_glutSpecialFunc(void (* f)(int key,int x,int y))1668 void GLUI_Master_Object::set_glutSpecialFunc(void (*f)(int key,
1669 						       int x, int y))
1670 {
1671   glutSpecialFunc( glui_special_func );
1672   add_cb_to_glut_window( glutGetWindow(), GLUI_GLUT_SPECIAL, (void*) f);
1673 }
1674 
1675 
1676 /*********************** GLUI_Master_Object::set_glutMouseFunc() **********/
1677 
set_glutMouseFunc(void (* f)(int button,int state,int x,int y))1678 void GLUI_Master_Object::set_glutMouseFunc(void (*f)(int button, int state,
1679 						     int x, int y))
1680 {
1681   glutMouseFunc( glui_mouse_func );
1682   add_cb_to_glut_window( glutGetWindow(), GLUI_GLUT_MOUSE, (void*) f);
1683 }
1684 
1685 
1686 /****************************** glui_parent_window_reshape_func() **********/
1687 /* This is the reshape callback for a window that contains subwindows      */
1688 
glui_parent_window_reshape_func(int w,int h)1689 void glui_parent_window_reshape_func( int w, int h )
1690 {
1691   int   current_window;
1692   GLUI  *glui;
1693   int   first = true;
1694 
1695   /*  printf( "glui_parent_window_reshape_func: %d\n", glutGetWindow() );          */
1696 
1697   current_window = glutGetWindow();
1698 
1699   glui = (GLUI*) GLUI_Master.gluis.first_child();
1700   while( glui ) {
1701     if ( TEST_AND( glui->flags, GLUI_SUBWINDOW) AND
1702 	 glui->parent_window == current_window ) {
1703       glutSetWindow( glui->get_glut_window_id());
1704       glui->check_subwindow_position();
1705       glutSetWindow( current_window );
1706 
1707       if ( first ) {
1708         if (glui->glut_reshape_CB) glui->glut_reshape_CB( w, h );
1709 
1710         first = false;
1711       }
1712     }
1713 
1714     glui = (GLUI*) glui->next();
1715   }
1716 }
1717 
1718 
1719 /****************************** glui_parent_window_keyboard_func() **********/
1720 
glui_parent_window_keyboard_func(unsigned char key,int x,int y)1721 void glui_parent_window_keyboard_func(unsigned char key, int x, int y)
1722 {
1723   /*  printf( "glui_parent_window_keyboard_func: %d\n", glutGetWindow() );          */
1724 
1725   int   current_window;
1726   GLUI  *glui;
1727 
1728   current_window = glutGetWindow();
1729 
1730   if ( GLUI_Master.active_control_glui AND GLUI_Master.active_control ) {
1731     glutSetWindow( GLUI_Master.active_control_glui->get_glut_window_id() );
1732 
1733     GLUI_Master.active_control_glui->keyboard(key,x,y);
1734 
1735     glutSetWindow( current_window );
1736   }
1737   else {
1738     glui = (GLUI*) GLUI_Master.gluis.first_child();
1739     while( glui ) {
1740       if ( TEST_AND( glui->flags, GLUI_SUBWINDOW) AND
1741            glui->parent_window == current_window AND
1742            glui->glut_keyboard_CB )
1743       {
1744         glui->glut_keyboard_CB( key, x, y );
1745         break;
1746       }
1747 
1748       glui = (GLUI*) glui->next();
1749     }
1750   }
1751 }
1752 
1753 
1754 /****************************** glui_parent_window_special_func() **********/
1755 
glui_parent_window_special_func(int key,int x,int y)1756 void glui_parent_window_special_func(int key, int x, int y)
1757 {
1758   /*printf( "glui_parent_window_special_func: %d\n", glutGetWindow() );          */
1759 
1760   int   current_window;
1761   GLUI  *glui;
1762 
1763   /**  If clicking in the main area of a window w/subwindows,
1764     deactivate any current control  **/
1765   if ( GLUI_Master.active_control_glui != NULL )
1766     GLUI_Master.active_control_glui->deactivate_current_control();
1767 
1768   /***   Now pass on the mouse event   ***/
1769 
1770   current_window = glutGetWindow();
1771 
1772   glui = (GLUI*) GLUI_Master.gluis.first_child();
1773   while( glui ) {
1774     if ( TEST_AND( glui->flags, GLUI_SUBWINDOW) AND
1775          glui->parent_window == current_window )
1776     {
1777       glutSetWindow( glui->get_glut_window_id());
1778       if (glui->glut_special_CB) glui->glut_special_CB( key, x, y );
1779       break;
1780     }
1781 
1782     glui = (GLUI*) glui->next();
1783   }
1784 }
1785 
1786 
1787 /****************************** glui_parent_window_mouse_func() **********/
1788 
glui_parent_window_mouse_func(int button,int state,int x,int y)1789 void glui_parent_window_mouse_func(int button, int state, int x, int y)
1790 {
1791   int   current_window;
1792   GLUI  *glui;
1793 
1794   /**  If clicking in the main area of a window w/subwindows,
1795     deactivate any current control  **/
1796   if ( GLUI_Master.active_control_glui != NULL )
1797     GLUI_Master.active_control_glui->deactivate_current_control();
1798 
1799 
1800   /***   Now pass on the mouse event   ***/
1801 
1802   current_window = glutGetWindow();
1803 
1804   glui = (GLUI*) GLUI_Master.gluis.first_child();
1805   while( glui ) {
1806     if ( TEST_AND( glui->flags, GLUI_SUBWINDOW) AND
1807          glui->parent_window == current_window AND
1808          glui->glut_mouse_CB)
1809     {
1810       glutSetWindow( glui->get_glut_window_id());
1811       glui->glut_mouse_CB( button, state, x, y );
1812       break;
1813     }
1814 
1815     glui = (GLUI*) glui->next();
1816   }
1817 }
1818 
1819 
1820 /************************** GLUI_Master_Object::find_glut_window() **********/
1821 
find_glut_window(int window_id)1822 GLUI_Glut_Window  *GLUI_Master_Object::find_glut_window( int window_id )
1823 {
1824   GLUI_Glut_Window *window;
1825 
1826   window = (GLUI_Glut_Window*) glut_windows.first_child();
1827   while( window ) {
1828     if ( window->glut_window_id == window_id )
1829       return window;
1830 
1831     window = (GLUI_Glut_Window*) window->next();
1832   }
1833 
1834   /***  Window not found - return NULL ***/
1835   return NULL;
1836 }
1837 
1838 
1839 /******************** GLUI_Master_Object::add_cb_to_glut_window() **********/
1840 
add_cb_to_glut_window(int window_id,int cb_type,void * cb)1841 void     GLUI_Master_Object::add_cb_to_glut_window(int window_id,
1842 						   int cb_type,void *cb)
1843 {
1844   GLUI_Glut_Window *window;
1845 
1846   window = find_glut_window( window_id );
1847   if ( NOT window ) {
1848     /***  Allocate new window structure  ***/
1849 
1850     window                 = new GLUI_Glut_Window;
1851     window->glut_window_id = window_id;
1852     window->link_this_to_parent_last( (GLUI_Node*) &this->glut_windows );
1853   }
1854 
1855   switch( cb_type ) {
1856   case GLUI_GLUT_RESHAPE:
1857     window->glut_reshape_CB   = (void(*)(int,int)) cb;
1858     break;
1859   case GLUI_GLUT_DISPLAY:
1860     window->glut_display_CB   = (void(*)()) cb;
1861     break;
1862   case GLUI_GLUT_KEYBOARD:
1863     window->glut_keyboard_CB  = (void(*)(unsigned char,int,int)) cb;
1864     break;
1865   case GLUI_GLUT_SPECIAL:
1866     window->glut_special_CB   = (void(*)(int,int,int)) cb;
1867     break;
1868   case GLUI_GLUT_MOUSE:
1869     window->glut_mouse_CB     = (void(*)(int,int,int,int)) cb;
1870     break;
1871   case GLUI_GLUT_MOTION:
1872     window->glut_motion_CB    = (void(*)(int,int)) cb;
1873     break;
1874   case GLUI_GLUT_PASSIVE_MOTION:
1875     window->glut_passive_motion_CB = (void(*)(int,int)) cb;
1876     break;
1877   case GLUI_GLUT_ENTRY:
1878     window->glut_entry_CB     = (void(*)(int)) cb;
1879     break;
1880   case GLUI_GLUT_VISIBILITY:
1881     window->glut_visibility_CB= (void(*)(int)) cb;
1882     break;
1883   }
1884 }
1885 
1886 
1887 /************* GLUI_Master_Object::set_left_button_glut_menu_control() *****/
1888 
set_left_button_glut_menu_control(GLUI_Control * control)1889 void  GLUI_Master_Object::set_left_button_glut_menu_control(
1890 							    GLUI_Control *control )
1891 {
1892   curr_left_button_glut_menu = control;
1893 }
1894 
1895 
1896 /******************************* GLUI_Main::set_ortho_projection() **********/
1897 
set_ortho_projection(void)1898 void  GLUI_Main::set_ortho_projection( void )
1899 {
1900   int win_h, win_w;
1901 
1902   win_w = glutGet( GLUT_WINDOW_WIDTH );
1903   win_h = glutGet( GLUT_WINDOW_HEIGHT );
1904 
1905   glMatrixMode( GL_PROJECTION );
1906   glLoadIdentity();
1907   /*  gluOrtho2D( 0.0, (float) win_w, 0.0, (float) win_h );          */
1908   glOrtho( 0.0, (float)win_w, 0.0, (float) win_h, -1000.0, 1000.0 );
1909 
1910   glMatrixMode( GL_MODELVIEW );
1911 
1912   return; /****-----------------------------------------------***/
1913 
1914   glMatrixMode( GL_MODELVIEW );
1915   glLoadIdentity();
1916 
1917   /*** Rotate image so y increases upwards, contrary to OpenGL axes ***/
1918   glTranslatef( (float) win_w/2.0, (float) win_h/2.0, 0.0 );
1919   glRotatef( 180.0, 0.0, 1.0, 0.0 );
1920   glRotatef( 180.0, 0.0, 0.0, 1.0 );
1921   glTranslatef( (float) -win_w/2.0, (float) -win_h/2.0, 0.0 );
1922 }
1923 
1924 
1925 /******************************* GLUI_Main::set_viewport() **********/
1926 
set_viewport(void)1927 void  GLUI_Main::set_viewport( void )
1928 {
1929   glViewport( 0, 0, main_panel->w, main_panel->h );
1930 }
1931 
1932 
1933 /****************************** GLUI_Main::refresh() ****************/
1934 
refresh(void)1935 void    GLUI_Main::refresh( void )
1936 {
1937   int orig;
1938 
1939   /******  GLUI_Glut_Window *glut_window;
1940     int              current_window;
1941     current_window = glutGetWindow();
1942     glut_window    = GLUI_Master.find_glut_window( current_window );
1943     if ( glut_window ) {
1944     glut_window->glut_reshape_CB(w,h);
1945     ******/
1946 
1947   orig  = glutGetWindow();
1948 
1949   pack_controls();
1950 
1951   if ( glut_window_id > 0 )
1952     glutSetWindow( glut_window_id );
1953 
1954 
1955   if ( TEST_AND( this->flags, GLUI_SUBWINDOW ) ) {
1956     /*** GLUI subwindow ***/
1957 
1958     check_subwindow_position();
1959   }
1960   else {
1961     /*** Standalone GLUI window ***/
1962 
1963     glutReshapeWindow( this->h, this->w );
1964 
1965   }
1966 
1967   glutPostRedisplay();
1968   glutSetWindow( orig);
1969 }
1970 
1971 
1972 
1973 /***************** GLUI_Master_Object::get_main_gfx_viewport() ***********/
1974 
get_viewport_area(int * x,int * y,int * w,int * h)1975 void     GLUI_Master_Object::get_viewport_area( int *x, int *y,
1976 						int *w, int *h )
1977 {
1978   GLUI *curr_glui;
1979   int   curr_x, curr_y, curr_w, curr_h;
1980   int   curr_window;
1981 
1982   curr_window = glutGetWindow();
1983   curr_x = 0;
1984   curr_y = 0;
1985   curr_w = glutGet( GLUT_WINDOW_WIDTH );
1986   curr_h = glutGet( GLUT_WINDOW_HEIGHT );
1987 
1988   curr_glui = (GLUI*) gluis.first_child();
1989   while( curr_glui ) {
1990     if ( TEST_AND( curr_glui->flags, GLUI_SUBWINDOW) AND
1991 	 curr_glui->parent_window == curr_window ) {
1992 
1993       /*			printf( "%s -> %d   %d %d\n", curr_glui->window_name.c_str(), curr_glui->flags,
1994 				curr_glui->w, curr_glui->h );*/
1995 
1996       if ( TEST_AND( curr_glui->flags,GLUI_SUBWINDOW_LEFT ) ) {
1997 	curr_x += curr_glui->w;
1998 	curr_w -= curr_glui->w;
1999       }
2000       else if ( TEST_AND( curr_glui->flags,GLUI_SUBWINDOW_BOTTOM ) ) {
2001 	curr_y += curr_glui->h;
2002 	curr_h -= curr_glui->h;
2003       }
2004       else if ( TEST_AND( curr_glui->flags,GLUI_SUBWINDOW_RIGHT ) ) {
2005 	curr_w -= curr_glui->w;
2006       }
2007       else if ( TEST_AND( curr_glui->flags,GLUI_SUBWINDOW_TOP ) ) {
2008 	curr_h -= curr_glui->h;
2009       }
2010     }
2011 
2012     curr_glui = (GLUI*) curr_glui->next();
2013   }
2014 
2015   curr_x = MAX( 0, curr_x );
2016   curr_y = MAX( 0, curr_y );
2017   curr_w = MAX( 0, curr_w );
2018   curr_h = MAX( 0, curr_h );
2019 
2020   *x = curr_x;
2021   *y = curr_y;
2022   *w = curr_w;
2023   *h = curr_h;
2024 }
2025 
2026 
2027 /*****************GLUI_Master_Object::auto_set_main_gfx_viewport() **********/
2028 
auto_set_viewport(void)2029 void           GLUI_Master_Object::auto_set_viewport( void )
2030 {
2031   int x, y, w, h;
2032 
2033   get_viewport_area( &x, &y, &w, &h );
2034   glViewport( MAX(x,0), MAX(y,0), MAX(w,0), MAX(h,0) );
2035 }
2036 
2037 
2038 
2039 /***************************************** GLUI::show() **********************/
2040 
show(void)2041 void            GLUI::show( void )
2042 {
2043   int orig_window;
2044 
2045   orig_window = main_panel->set_to_glut_window();
2046 
2047   glutShowWindow();
2048 
2049   main_panel->restore_window(orig_window);
2050 }
2051 
2052 
2053 
2054 /***************************************** GLUI::hide() **********************/
2055 
hide(void)2056 void            GLUI::hide( void )
2057 {
2058   int orig_window;
2059 
2060   this->deactivate_current_control();
2061 
2062   orig_window = main_panel->set_to_glut_window();
2063 
2064   glutHideWindow();
2065 
2066   main_panel->restore_window(orig_window);
2067 }
2068 
2069 
2070 /**************** GLUI_DrawingSentinal **************/
GLUI_DrawingSentinal(GLUI_Control * c_)2071 GLUI_DrawingSentinal::GLUI_DrawingSentinal(GLUI_Control *c_)
2072 	:c(c_)
2073 {
2074 	orig_win = c->set_to_glut_window();
2075 	orig_buf = c->glui->set_current_draw_buffer();
2076 }
~GLUI_DrawingSentinal()2077 GLUI_DrawingSentinal::~GLUI_DrawingSentinal() {
2078 	c->glui->restore_draw_buffer(orig_buf);
2079 	c->restore_window(orig_win);
2080 }
2081 
2082 
glui_setIdleFuncIfNecessary(void)2083 void GLUI_Master_Object::glui_setIdleFuncIfNecessary( void )
2084 {
2085   GLUI *glui;
2086 
2087   glui = (GLUI*) GLUI_Master.gluis.first_child();
2088   int necessary;
2089   if (this->glut_idle_CB)
2090     necessary = true;
2091   else {
2092     necessary = false;
2093     while( glui ) {
2094       if( glui->needs_idle() ) {
2095 	necessary = true;
2096 	break;
2097       }
2098       glui = (GLUI*) glui->next();
2099     }
2100   }
2101   if( necessary )
2102     glutIdleFunc( glui_idle_func );
2103   else
2104     glutIdleFunc( NULL );
2105 }
2106