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