prevent resize callback (and indeed the whole resizing logic) from getting
[freeglut] / progs / demos / CallbackMaker / CallbackMaker.c
index 88cc3d3..5027ca5 100644 (file)
@@ -14,46 +14,31 @@ static int sequence_number = 0 ;
 int windows[2] = {0};
 
 /* define status vars showing whether given callback has been called for given window */
-#define CALLBACK_CALLED_VAR(name) int name##_called[2] = {0};
-#define CALLBACK_1_VAR(name,field) int name##_##field[2], name##_seq[2] = {-1};
-#define CALLBACK_2_VARS(name,field1,field2) int name##_##field1[2], name##_##field2[2], name##_seq[2] = {-1};
-#define CALLBACK_3_VARS(name,field1,field2,field3) int name##_##field1[2], name##_##field2[2], name##_##field3[2], name##_seq[2] = {-1};
-#define CALLBACK_4_VARS(name,field1,field2,field3,field4) int name##_##field1[2], name##_##field2[2], name##_##field3[2], name##_##field4[2], name##_seq[2] = {-1};
-CALLBACK_CALLED_VAR(reshape);
-CALLBACK_2_VARS(reshape,width,height);
-CALLBACK_CALLED_VAR(key);
-CALLBACK_3_VARS(key,key,x,y);
-CALLBACK_CALLED_VAR(keyup);
-CALLBACK_3_VARS(keyup,key,x,y);
-CALLBACK_CALLED_VAR(special);
-CALLBACK_3_VARS(special,key,x,y);
-CALLBACK_CALLED_VAR(specialup);
-CALLBACK_3_VARS(specialup,key,x,y);
-CALLBACK_CALLED_VAR(visibility);
-CALLBACK_1_VAR(visibility,vis);
-CALLBACK_CALLED_VAR(joystick);
-CALLBACK_4_VARS(joystick,a,b,c,d);
-CALLBACK_CALLED_VAR(mouse);
-CALLBACK_4_VARS(mouse,button,updown,x,y);
-CALLBACK_CALLED_VAR(mousewheel);
-CALLBACK_4_VARS(mousewheel,number,direction,x,y);
-CALLBACK_CALLED_VAR(motion);
-CALLBACK_2_VARS(motion,x,y);
-CALLBACK_CALLED_VAR(passivemotion);
-CALLBACK_2_VARS(passivemotion,x,y);
-CALLBACK_CALLED_VAR(entry);
-CALLBACK_CALLED_VAR(close);
-/*CALLBACK_CALLED_VAR(overlaydisplay);
-CALLBACK_CALLED_VAR(windowstatus);
-CALLBACK_CALLED_VAR(spacemotion);
-CALLBACK_CALLED_VAR(spacerotation);
-CALLBACK_CALLED_VAR(spacebutton);
-CALLBACK_CALLED_VAR(buttonbox);
-CALLBACK_CALLED_VAR(dials);
-CALLBACK_CALLED_VAR(tabletmotion);
-CALLBACK_CALLED_VAR(tabletbutton);
-CALLBACK_CALLED_VAR(menustatus);*/
-int menudestroy_called = 0 ;    /* menudestroy is registered on menu, so don't use above */
+#define CALLBACK_CALLED_VAR(name)                     int name##_called[2]   = {0};
+#define CALLBACK_0V(name)                             int name##_seq[2]      = {-1}; CALLBACK_CALLED_VAR(name); 
+#define CALLBACK_1V(name,field)                       int name##_##field[2]  = {-1}; CALLBACK_0V(name);
+#define CALLBACK_2V(name,field1,field2)               int name##_##field2[2] = {-1}; CALLBACK_1V(name,field1);
+#define CALLBACK_3V(name,field1,field2,field3)        int name##_##field3[2] = {-1}; CALLBACK_2V(name,field1,field2);
+#define CALLBACK_4V(name,field1,field2,field3,field4) int name##_##field4[2] = {-1}; CALLBACK_3V(name,field1,field2,field3);
+CALLBACK_2V(reshape,width,height);
+CALLBACK_2V(position,top,left);
+CALLBACK_3V(key,key,x,y);
+CALLBACK_3V(keyup,key,x,y);
+CALLBACK_3V(special,key,x,y);
+CALLBACK_3V(specialup,key,x,y);
+CALLBACK_1V(visibility,vis);
+CALLBACK_4V(joystick,a,b,c,d);
+CALLBACK_4V(mouse,button,updown,x,y);
+CALLBACK_4V(mousewheel,number,direction,x,y);
+CALLBACK_2V(motion,x,y);
+CALLBACK_2V(passivemotion,x,y);
+CALLBACK_0V(entry);
+CALLBACK_0V(close);
+/* menudestroy is registered on each menu, not a window */
+int menudestroy_called = 0 ;
+/* menustatus and menustate are global callbacks, set for all menus at the same time */
+int menustatus_called = 0;
+int menustate_called = 0;
 
 #define STRING_LENGTH   10
 
@@ -108,6 +93,11 @@ Display(void)
     bitmapPrintf ( "Reshape %d:  %d %d\n", reshape_seq[winIdx], reshape_width[winIdx], reshape_height[winIdx] );
   }
 
+  if ( position_called[winIdx] )
+  {
+    bitmapPrintf ( "Position %d:  %d %d\n", position_seq[winIdx], position_left[winIdx], position_top[winIdx] );
+  }
+
   if ( key_called[winIdx] )
   {
     bitmapPrintf ( "Key %d:  %d(%c) %d %d\n", key_seq[winIdx], key_key[winIdx], key_key[winIdx], key_x[winIdx], key_y[winIdx] );
@@ -213,6 +203,20 @@ Reshape(int width, int height)
 }
 
 static void 
+Position(int left, int top)
+{
+  int winIdx;
+  int window = getWindowAndIdx(&winIdx);
+  printf ( "%6d Window %d Position Callback:  %d %d\n",
+            ++sequence_number, window, left, top ) ;
+  position_called[winIdx] = 1 ;
+  position_left[winIdx] = left ;
+  position_top[winIdx] = top ;
+  position_seq[winIdx] = sequence_number ;
+  glutPostRedisplay () ;
+}
+
+static void 
 Key(unsigned char key, int x, int y)
 {
   int winIdx;
@@ -460,32 +464,45 @@ TabletButton(int button, int updown, int x, int y)
 }
 
 static void
-MenuCallback ( int menuID )
+MenuCallback ( int value )
 {
+  int menu = glutGetMenu();
   int window = getWindowAndIdx(NULL);
-  printf( "%6d Window %d MenuCallback - menuID is %d\n",
-          ++sequence_number, window, menuID );
+  printf( "%6d Menu %d MenuCallback for menu opened in Window %d - value is %d\n",
+          ++sequence_number, menu, window, value );
 }
 
 static void 
 MenuDestroy( void )
 {
-  int window = getWindowAndIdx(NULL);
+  int menu = glutGetMenu();
   menudestroy_called = 1 ;
-  printf ( "%6d Window %d MenuDestroy Callback\n",
-            ++sequence_number, window ) ;
-
-  if (window)   /* When destroyed when shutting down, not always a window defined... */
-    glutPostRedisplay () ;
+  printf ( "%6d Menu %d MenuDestroy Callback\n",
+            ++sequence_number, menu ) ;
 }
 
 static void 
 MenuStatus( int status, int x, int y )
 {
+  /* Menu and window for which this event is triggered are current when the callback is called */
+  int menu = glutGetMenu();
   int window = getWindowAndIdx(NULL);
-  menudestroy_called = 1 ;
-  printf ( "%6d Window %d MenuStatus Callback:  %d %d %d\n",
-            ++sequence_number, window, status, x, y ) ;
+  menustatus_called = 1 ;
+  printf ( "%6d Menu %d MenuStatus Callback in Window %d:  %d %d %d\n",
+            ++sequence_number, menu, window, status, x, y ) ;
+  glutPostRedisplay () ;
+}
+
+
+static void 
+MenuState( int status )
+{
+  /* Menu and window for which this event is triggered are current when the callback is called */
+  int menu = glutGetMenu();
+  int window = getWindowAndIdx(NULL);
+  menustate_called = 1 ;
+  printf ( "%6d Menu %d MenuState Callback in Window %d:  %d\n",
+            ++sequence_number, menu, window, status) ;
   glutPostRedisplay () ;
 }
 
@@ -509,13 +526,20 @@ main(int argc, char *argv[])
   glutInit(&argc, argv);
   glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE,GLUT_ACTION_CONTINUE_EXECUTION);
 
+  /* Set other global callback (global as in not associated with any specific menu or window) */
+  glutIdleFunc ( Idle );
+  glutMenuStatusFunc ( MenuStatus );
+  glutMenuStateFunc  ( MenuState ); /* Note that glutMenuStatusFunc is an enhanced version of the deprecated glutMenuStateFunc. */
+
   windows[0] = glutCreateWindow( "Callback Demo" );
   printf ( "Creating window %d as 'Callback Demo'\n", windows[0] ) ;
 
   glClearColor(1.0, 1.0, 1.0, 1.0);
 
+  /* callbacks and settings specific to this window */
   glutDisplayFunc( Display );
   glutReshapeFunc( Reshape );
+  glutPositionFunc( Position );
   glutKeyboardFunc( Key );
   glutSpecialFunc( Special );
   glutVisibilityFunc( Visibility );
@@ -537,31 +561,30 @@ main(int argc, char *argv[])
   glutDialsFunc ( Dials ) ;
   glutTabletMotionFunc ( TabletMotion ) ;
   glutTabletButtonFunc ( TabletButton ) ;
-  glutMenuStatusFunc ( MenuStatus );
   glutSetKeyRepeat(GLUT_KEY_REPEAT_OFF) ;
 
   subMenuA = glutCreateMenu( MenuCallback );
-  glutAddMenuEntry( "Sub menu A1 (01)", 1 );
-  glutAddMenuEntry( "Sub menu A2 (02)", 2 );
-  glutAddMenuEntry( "Sub menu A3 (03)", 3 );
-  glutMenuDestroyFunc ( MenuDestroy );
+  glutAddMenuEntry( "Sub menu A1 (01)", 11 );
+  glutAddMenuEntry( "Sub menu A2 (02)", 12 );
+  glutAddMenuEntry( "Sub menu A3 (03)", 13 );
+  glutMenuDestroyFunc ( MenuDestroy );  /* callback specific to this menu */
 
   subMenuB = glutCreateMenu( MenuCallback );
-  glutAddMenuEntry( "Sub menu B1 (04)", 4 );
-  glutAddMenuEntry( "Sub menu B2 (05)", 5 );
-  glutAddMenuEntry( "Sub menu B3 (06)", 6 );
+  glutAddMenuEntry( "Sub menu B1 (04)", 14 );
+  glutAddMenuEntry( "Sub menu B2 (05)", 15 );
+  glutAddMenuEntry( "Sub menu B3 (06)", 16 );
   glutAddSubMenu( "Going to sub menu A", subMenuA );
-  glutMenuDestroyFunc ( MenuDestroy );
+  glutMenuDestroyFunc ( MenuDestroy );  /* callback specific to this menu */
 
   menuID = glutCreateMenu( MenuCallback );
-  glutAddMenuEntry( "Entry one",   1 );
-  glutAddMenuEntry( "Entry two",   2 );
-  glutAddMenuEntry( "Entry three", 3 );
-  glutAddMenuEntry( "Entry four",  4 );
-  glutAddMenuEntry( "Entry five",  5 );
+  glutAddMenuEntry( "Entry one",   21 );
+  glutAddMenuEntry( "Entry two",   22 );
+  glutAddMenuEntry( "Entry three", 23 );
+  glutAddMenuEntry( "Entry four",  24 );
+  glutAddMenuEntry( "Entry five",  25 );
   glutAddSubMenu( "Enter sub menu A", subMenuA );
   glutAddSubMenu( "Enter sub menu B", subMenuB );
-  glutMenuDestroyFunc ( MenuDestroy );
+  glutMenuDestroyFunc ( MenuDestroy );  /* callback specific to this menu */
 
   glutAttachMenu( GLUT_LEFT_BUTTON );
 
@@ -572,8 +595,10 @@ main(int argc, char *argv[])
 
   glClearColor(1.0, 1.0, 1.0, 1.0);
 
+  /* callbacks and settings specific to this window */
   glutDisplayFunc( Display );
   glutReshapeFunc( Reshape );
+  glutPositionFunc( Position );
   glutKeyboardFunc( Key );
   glutSpecialFunc( Special );
   glutVisibilityFunc( Visibility );
@@ -597,7 +622,9 @@ main(int argc, char *argv[])
   glutTabletButtonFunc ( TabletButton ) ;
   glutSetKeyRepeat(GLUT_KEY_REPEAT_OFF) ;
 
-  glutIdleFunc ( Idle );
+  glutSetMenu(subMenuB);
+  glutAttachMenu( GLUT_RIGHT_BUTTON );
+
 
   printf ( "Please enter something to continue: " );
   fgets ( dummy_string, STRING_LENGTH, stdin );
@@ -606,5 +633,5 @@ main(int argc, char *argv[])
 
   printf ( "Back from the 'freeglut' main loop\n" ) ;
 
-  return 0;             /* ANSI C requires main to return int. */
+  return EXIT_SUCCESS;
 }