small enhancement to Callbackmaker demo
[freeglut] / progs / demos / CallbackMaker / CallbackMaker.c
1 /* CallbackMaker.c */
2 /*
3  * Program to invoke all the callbacks that "freeglut" supports
4  */
5
6
7 #include <GL/freeglut.h>
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <stdarg.h>
11
12 static int sequence_number = 0 ;
13
14 int reshape_called = 0, key_called = 0, special_called = 0, visibility_called = 0,
15     keyup_called = 0, specialup_called = 0, joystick_called = 0, mouse_called = 0,
16     mousewheel_called = 0, motion_called = 0, passivemotion_called = 0, entry_called = 0,
17     close_called = 0, overlaydisplay_called = 0, windowstatus_called = 0,
18     spacemotion_called = 0, spacerotation_called = 0, spacebutton_called = 0,
19     buttonbox_called = 0, dials_called = 0, tabletmotion_called = 0, tabletbutton_called = 0,
20     menudestroy_called = 0, menustatus_called = 0 ;
21 int reshape_width = -1, reshape_height = -1, reshape_seq = -1 ;
22 int key_key = -1, key_x = -1, key_y = -1, key_seq = -1 ;
23 int special_key = -1, special_x = -1, special_y = -1, special_seq = -1 ;
24 int visibility_vis = -1, visibility_seq = -1 ;
25 int keyup_key = -1, keyup_x = -1, keyup_y = -1, keyup_seq = -1 ;
26 int specialup_key = -1, specialup_x = -1, specialup_y = -1, specialup_seq = -1 ;
27 int joystick_a = -1, joystick_b = -1, joystick_c = -1, joystick_d = -1, joystick_seq = -1 ;  /* Need meaningful names */
28 int mouse_button = -1, mouse_updown = -1, mouse_x = -1, mouse_y = -1, mouse_seq = -1 ;
29 int mousewheel_number = -1, mousewheel_direction = -1, mousewheel_x = -1, mousewheel_y = -1, mousewheel_seq = -1 ;
30 int motion_x = -1, motion_y = -1, motion_seq = -1 ;
31 int passivemotion_x = -1, passivemotion_y = -1, passivemotion_seq = -1 ;
32
33 #define STRING_LENGTH   10
34
35 static void
36 bitmapPrintf (const char *fmt, ...)
37 {
38     static char buf[256];
39     va_list args;
40
41     va_start(args, fmt);
42 #if defined(WIN32) && !defined(__CYGWIN__)
43     (void) _vsnprintf (buf, sizeof(buf), fmt, args);
44 #else
45     (void) vsnprintf (buf, sizeof(buf), fmt, args);
46 #endif
47     va_end(args);
48     glutBitmapString ( GLUT_BITMAP_HELVETICA_12, (unsigned char*)buf ) ;
49 }
50
51
52 static void 
53 Display(void)
54 {
55   int window = glutGetWindow () ;
56   glClear ( GL_COLOR_BUFFER_BIT );
57
58   glDisable ( GL_DEPTH_TEST );
59   glMatrixMode ( GL_PROJECTION );
60   glPushMatrix();
61   glLoadIdentity();
62   glOrtho(0, glutGet ( GLUT_WINDOW_WIDTH ), 
63           0, glutGet ( GLUT_WINDOW_HEIGHT ), -1, 1 );
64   glMatrixMode ( GL_MODELVIEW );
65   glPushMatrix ();
66   glLoadIdentity ();
67   glColor3ub ( 0, 0, 0 );
68   glRasterPos2i ( 10, glutGet ( GLUT_WINDOW_HEIGHT ) - 20 );    /* 10pt margin above 10pt letters */
69
70   if ( reshape_called )
71   {
72     bitmapPrintf ( "Reshape %d:  %d %d\n", reshape_seq, reshape_width, reshape_height );
73   }
74
75   if ( key_called )
76   {
77     bitmapPrintf ( "Key %d:  %d(%c) %d %d\n", key_seq, key_key, key_key, key_x, key_y );
78   }
79
80   if ( special_called )
81   {
82     bitmapPrintf ( "Special %d:  %d(%c) %d %d\n", special_seq, special_key, special_key, special_x, special_y );
83   }
84
85   if ( visibility_called )
86   {
87     bitmapPrintf ( "Visibility %d:  %d\n", visibility_seq, visibility_vis );
88   }
89
90   if ( keyup_called )
91   {
92     bitmapPrintf ( "Key Up %d:  %d(%c) %d %d\n", keyup_seq, keyup_key, keyup_key, keyup_x, keyup_y );
93   }
94
95   if ( specialup_called )
96   {
97     bitmapPrintf ( "Special Up %d:  %d(%c) %d %d\n", specialup_seq, specialup_key, specialup_key, specialup_x, specialup_y );
98   }
99
100   if ( joystick_called )
101   {
102     bitmapPrintf ( "Joystick %d:  %d %d %d %d\n", joystick_seq, joystick_a, joystick_b, joystick_c, joystick_d );
103   }
104
105   if ( mouse_called )
106   {
107     bitmapPrintf ( "Mouse %d:  %d %d %d %d\n", mouse_seq, mouse_button, mouse_updown, mouse_x, mouse_y );
108   }
109
110   if ( mousewheel_called )
111   {
112     bitmapPrintf ( "Mouse Wheel %d:  %d %d %d %d\n", mousewheel_seq, mousewheel_number, mousewheel_direction, mousewheel_x, mousewheel_y );
113   }
114
115   if ( motion_called )
116   {
117     bitmapPrintf ( "Motion %d:  %d %d\n", motion_seq, motion_x, motion_y );
118   }
119
120   if ( passivemotion_called )
121   {
122     bitmapPrintf ( "Passive Motion %d:  %d %d\n", passivemotion_seq, passivemotion_x, passivemotion_y );
123   }
124
125   glMatrixMode ( GL_PROJECTION );
126   glPopMatrix ();
127   glMatrixMode ( GL_MODELVIEW );
128   glPopMatrix ();
129   glEnable ( GL_DEPTH_TEST );
130
131   printf ( "%6d Window %d Display Callback\n",
132             ++sequence_number, window ) ;
133   glutSwapBuffers();
134 }
135
136 static void
137 Warning(const char *fmt, va_list ap)
138 {
139     printf("%6d Warning callback:\n");
140
141     /* print warning message */
142     vprintf(fmt, ap);
143 }
144
145 static void
146 Error(const char *fmt, va_list ap)
147 {
148     char dummy_string[STRING_LENGTH];
149     printf("%6d Error callback:\n");
150
151     /* print warning message */
152     vprintf(fmt, ap);
153
154     /* terminate program, after pause for input so user can see */
155     printf ( "Please enter something to exit: " );
156     fgets ( dummy_string, STRING_LENGTH, stdin );
157
158     /* Call exit directly as freeglut is messed
159      * up internally when an error is called. 
160      */
161     exit(1);
162 }
163
164 static void 
165 Reshape(int width, int height)
166 {
167   int window = glutGetWindow () ;
168   printf ( "%6d Window %d Reshape Callback:  %d %d\n",
169             ++sequence_number, window, width, height ) ;
170   reshape_called = 1 ;
171   reshape_width = width ;
172   reshape_height = height ;
173   reshape_seq = sequence_number ;
174   glViewport(0,0,width,height);
175   glutPostRedisplay () ;
176 }
177
178 static void 
179 Key(unsigned char key, int x, int y)
180 {
181   int window = glutGetWindow () ;
182   printf ( "%6d Window %d Keyboard Callback:  %d %d %d\n",
183             ++sequence_number, window, key, x, y ) ;
184   key_called = 1 ;
185   key_key = key ;
186   key_x = x ;
187   key_y = y ;
188   key_seq = sequence_number ;
189   glutPostRedisplay () ;
190 }
191
192 static void 
193 Special(int key, int x, int y)
194 {
195   int window = glutGetWindow () ;
196   printf ( "%6d Window %d Special Key Callback:  %d %d %d\n",
197             ++sequence_number, window, key, x, y ) ;
198   special_called = 1 ;
199   special_key = key ;
200   special_x = x ;
201   special_y = y ;
202   special_seq = sequence_number ;
203   glutPostRedisplay () ;
204 }
205
206 static void 
207 Visibility(int vis)
208 {
209   int window = glutGetWindow () ;
210   printf ( "%6d Window %d Visibility Callback:  %d\n",
211             ++sequence_number, window, vis ) ;
212   visibility_called = 1 ;
213   visibility_vis = vis ;
214   visibility_seq = sequence_number ;
215   glutPostRedisplay () ;
216 }
217
218 static void 
219 KeyUp(unsigned char key, int x, int y)
220 {
221   int window = glutGetWindow () ;
222   printf ( "%6d Window %d Key Release Callback:  %d %d %d\n",
223             ++sequence_number, window, key, x, y ) ;
224   keyup_called = 1 ;
225   keyup_key = key ;
226   keyup_x = x ;
227   keyup_y = y ;
228   keyup_seq = sequence_number ;
229   glutPostRedisplay () ;
230 }
231
232 static void 
233 SpecialUp(int key, int x, int y)
234 {
235   int window = glutGetWindow () ;
236   printf ( "%6d Window %d Special Key Release Callback:  %d %d %d\n",
237             ++sequence_number, window, key, x, y ) ;
238   specialup_called = 1 ;
239   specialup_key = key ;
240   specialup_x = x ;
241   specialup_y = y ;
242   specialup_seq = sequence_number ;
243   glutPostRedisplay () ;
244 }
245
246 static void 
247 Joystick( unsigned int a, int b, int c, int d)  /* Need meaningful names */
248 {
249   int window = glutGetWindow () ;
250   printf ( "%6d Window %d Joystick Callback:  %d %d %d %d\n",
251             ++sequence_number, window, a, b, c, d ) ;
252   joystick_called = 1 ;
253   joystick_a = a ;
254   joystick_b = b ;
255   joystick_c = c ;
256   joystick_d = d ;
257   joystick_seq = sequence_number ;
258   glutPostRedisplay () ;
259 }
260
261 static void 
262 Mouse(int button, int updown, int x, int y)
263 {
264   int window = glutGetWindow () ;
265   printf ( "%6d Window %d Mouse Click Callback:  %d %d %d %d\n",
266             ++sequence_number, window, button, updown, x, y ) ;
267   mouse_called = 1 ;
268   mouse_button = button ;
269   mouse_updown = updown ;
270   mouse_x = x ;
271   mouse_y = y ;
272   mouse_seq = sequence_number ;
273   glutPostRedisplay () ;
274 }
275
276 static void 
277 MouseWheel(int wheel_number, int direction, int x, int y)
278 {
279   int window = glutGetWindow () ;
280   printf ( "%6d Window %d Mouse Wheel Callback:  %d %d %d %d\n",
281             ++sequence_number, window, wheel_number, direction, x, y ) ;
282   mousewheel_called = 1 ;
283   mousewheel_number = wheel_number ;
284   mousewheel_direction = direction ;
285   mousewheel_x = x ;
286   mousewheel_y = y ;
287   mousewheel_seq = sequence_number ;
288   glutPostRedisplay () ;
289 }
290
291 static void 
292 Motion(int x, int y)
293 {
294   int window = glutGetWindow () ;
295   printf ( "%6d Window %d Mouse Motion Callback:  %d %d\n",
296             ++sequence_number, window, x, y ) ;
297   motion_called = 1 ;
298   motion_x = x ;
299   motion_y = y ;
300   motion_seq = sequence_number ;
301   glutPostRedisplay () ;
302 }
303
304 static void 
305 PassiveMotion(int x, int y)
306 {
307   int window = glutGetWindow () ;
308   printf ( "%6d Window %d Mouse Passive Motion Callback:  %d %d\n",
309             ++sequence_number, window, x, y ) ;
310   passivemotion_called = 1 ;
311   passivemotion_x = x ;
312   passivemotion_y = y ;
313   passivemotion_seq = sequence_number ;
314   glutPostRedisplay () ;
315 }
316
317 static void 
318 Entry(int state)
319 {
320   int window = glutGetWindow () ;
321   entry_called = 1 ;
322   printf ( "%6d Window %d Entry Callback:  %d\n",
323             ++sequence_number, window, state ) ;
324   glutPostRedisplay () ;
325 }
326
327 static void 
328 Close(void)
329 {
330   int window = glutGetWindow () ;
331   close_called = 1 ;
332   printf ( "%6d Window %d Close Callback\n",
333             ++sequence_number, window ) ;
334 }
335
336 static void 
337 OverlayDisplay(void)
338 {
339   int window = glutGetWindow () ;
340   overlaydisplay_called = 1 ;
341   printf ( "%6d Window %d OverlayDisplay Callback\n",
342             ++sequence_number, window ) ;
343   glutPostRedisplay () ;
344 }
345
346 static void 
347 WindowStatus(int state)
348 {
349   int window = glutGetWindow () ;
350   windowstatus_called = 1 ;
351   printf ( "%6d Window %d WindowStatus Callback:  %d\n",
352             ++sequence_number, window, state ) ;
353   glutPostRedisplay () ;
354 }
355
356 static void 
357 SpaceMotion(int x, int y, int z)
358 {
359   int window = glutGetWindow () ;
360   spacemotion_called = 1 ;
361   printf ( "%6d Window %d SpaceMotion Callback:  %d %d %d\n",
362             ++sequence_number, window, x, y, z ) ;
363   glutPostRedisplay () ;
364 }
365
366 static void 
367 SpaceRotation(int x, int y, int z)
368 {
369   int window = glutGetWindow () ;
370   spacerotation_called = 1 ;
371   printf ( "%6d Window %d SpaceRotation Callback:  %d %d %d\n",
372             ++sequence_number, window, x, y, z ) ;
373   glutPostRedisplay () ;
374 }
375
376 static void 
377 SpaceButton(int button, int updown)
378 {
379   int window = glutGetWindow () ;
380   spacebutton_called = 1 ;
381   printf ( "%6d Window %d SpaceButton Callback:  %d %d\n",
382             ++sequence_number, window, button, updown ) ;
383   glutPostRedisplay () ;
384 }
385
386 static void 
387 Dials(int x, int y)
388 {
389   int window = glutGetWindow () ;
390   dials_called = 1 ;
391   printf ( "%6d Window %d Dials Callback:  %d %d\n",
392             ++sequence_number, window, x, y ) ;
393   glutPostRedisplay () ;
394 }
395
396 static void 
397 ButtonBox(int button, int updown)
398 {
399   int window = glutGetWindow () ;
400   buttonbox_called = 1 ;
401   printf ( "%6d Window %d ButtonBox Callback:  %d %d\n",
402             ++sequence_number, window, button, updown ) ;
403   glutPostRedisplay () ;
404 }
405
406 static void 
407 TabletMotion(int x, int y)
408 {
409   int window = glutGetWindow () ;
410   tabletmotion_called = 1 ;
411   printf ( "%6d Window %d TabletMotion Callback:  %d %d\n",
412             ++sequence_number, window, x, y ) ;
413   glutPostRedisplay () ;
414 }
415
416 static void 
417 TabletButton(int button, int updown, int x, int y)
418 {
419   int window = glutGetWindow () ;
420   tabletbutton_called = 1 ;
421   printf ( "%6d Window %d TabletButton Callback:  %d %d %d %d\n",
422             ++sequence_number, window, button, updown, x, y ) ;
423   glutPostRedisplay () ;
424 }
425
426 static void
427 MenuCallback ( int menuID )
428 {
429   int window = glutGetWindow () ;
430   printf( "%6d Window %d MenuCallback - menuID is %d\n",
431           ++sequence_number, window, menuID );
432 }
433
434 static void 
435 MenuDestroy( void )
436 {
437   int window = glutGetWindow () ;
438   menudestroy_called = 1 ;
439   printf ( "%6d Window %d MenuDestroy Callback\n",
440             ++sequence_number, window ) ;
441
442   if (window)   /* When destroyed when shutting down, not always a window defined... */
443     glutPostRedisplay () ;
444 }
445
446 static void 
447 MenuStatus( int status, int x, int y )
448 {
449   int window = glutGetWindow () ;
450   menudestroy_called = 1 ;
451   printf ( "%6d Window %d MenuStatus Callback:  %d %d %d\n",
452             ++sequence_number, window, status, x, y ) ;
453   glutPostRedisplay () ;
454 }
455
456 static void Idle ( void )
457 {
458   ++sequence_number ;
459 }
460
461 int 
462 main(int argc, char *argv[])
463 {
464   int freeglut_window, aux_window ;
465   char dummy_string[STRING_LENGTH];
466
467   int menuID, subMenuA, subMenuB;
468
469   glutInitWarningFunc(Warning);
470   glutInitErrorFunc(Error);
471   glutInitWindowSize(500, 250);
472   glutInitWindowPosition ( 140, 140 );
473   glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE );
474   glutInit(&argc, argv);
475   glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE,GLUT_ACTION_CONTINUE_EXECUTION);
476
477   freeglut_window = glutCreateWindow( "Callback Demo" );
478   printf ( "Creating window %d as 'Callback Demo'\n", freeglut_window ) ;
479
480   glClearColor(1.0, 1.0, 1.0, 1.0);
481
482   glutDisplayFunc( Display );
483   glutReshapeFunc( Reshape );
484   glutKeyboardFunc( Key );
485   glutSpecialFunc( Special );
486   glutVisibilityFunc( Visibility );
487   glutKeyboardUpFunc( KeyUp );
488   glutSpecialUpFunc( SpecialUp );
489   glutJoystickFunc( Joystick, 100 );
490   glutMouseFunc ( Mouse ) ;
491   glutMouseWheelFunc ( MouseWheel ) ;
492   glutMotionFunc ( Motion ) ;
493   glutPassiveMotionFunc ( PassiveMotion ) ;
494   glutEntryFunc ( Entry ) ;
495   glutCloseFunc ( Close ) ;
496   glutOverlayDisplayFunc ( OverlayDisplay ) ;
497   glutWindowStatusFunc ( WindowStatus ) ;
498   glutSpaceballMotionFunc ( SpaceMotion ) ;
499   glutSpaceballRotateFunc ( SpaceRotation ) ;
500   glutSpaceballButtonFunc ( SpaceButton ) ;
501   glutButtonBoxFunc ( ButtonBox ) ;
502   glutDialsFunc ( Dials ) ;
503   glutTabletMotionFunc ( TabletMotion ) ;
504   glutTabletButtonFunc ( TabletButton ) ;
505   glutMenuStatusFunc ( MenuStatus );
506   glutSetKeyRepeat(GLUT_KEY_REPEAT_OFF) ;
507
508   subMenuA = glutCreateMenu( MenuCallback );
509   glutAddMenuEntry( "Sub menu A1 (01)", 1 );
510   glutAddMenuEntry( "Sub menu A2 (02)", 2 );
511   glutAddMenuEntry( "Sub menu A3 (03)", 3 );
512   glutMenuDestroyFunc ( MenuDestroy );
513
514   subMenuB = glutCreateMenu( MenuCallback );
515   glutAddMenuEntry( "Sub menu B1 (04)", 4 );
516   glutAddMenuEntry( "Sub menu B2 (05)", 5 );
517   glutAddMenuEntry( "Sub menu B3 (06)", 6 );
518   glutAddSubMenu( "Going to sub menu A", subMenuA );
519   glutMenuDestroyFunc ( MenuDestroy );
520
521   menuID = glutCreateMenu( MenuCallback );
522   glutAddMenuEntry( "Entry one",   1 );
523   glutAddMenuEntry( "Entry two",   2 );
524   glutAddMenuEntry( "Entry three", 3 );
525   glutAddMenuEntry( "Entry four",  4 );
526   glutAddMenuEntry( "Entry five",  5 );
527   glutAddSubMenu( "Enter sub menu A", subMenuA );
528   glutAddSubMenu( "Enter sub menu B", subMenuB );
529   glutMenuDestroyFunc ( MenuDestroy );
530
531   glutAttachMenu( GLUT_LEFT_BUTTON );
532
533   aux_window = glutCreateWindow( "Second Window" );
534   printf ( "Creating window %d as 'Second Window'\n", aux_window ) ;
535
536   glClearColor(1.0, 1.0, 1.0, 1.0);
537
538   glutDisplayFunc( Display );
539   glutReshapeFunc( Reshape );
540   glutKeyboardFunc( Key );
541   glutSpecialFunc( Special );
542   glutVisibilityFunc( Visibility );
543   glutKeyboardUpFunc( KeyUp );
544   glutSpecialUpFunc( SpecialUp );
545   /*  glutJoystickFunc( Joystick, 100 ); */
546   glutMouseFunc ( Mouse ) ;
547   glutMouseWheelFunc ( MouseWheel ) ;
548   glutMotionFunc ( Motion ) ;
549   glutPassiveMotionFunc ( PassiveMotion ) ;
550   glutEntryFunc ( Entry ) ;
551   glutCloseFunc ( Close ) ;
552   glutOverlayDisplayFunc ( OverlayDisplay ) ;
553   glutWindowStatusFunc ( WindowStatus ) ;
554   glutSpaceballMotionFunc ( SpaceMotion ) ;
555   glutSpaceballRotateFunc ( SpaceRotation ) ;
556   glutSpaceballButtonFunc ( SpaceButton ) ;
557   glutButtonBoxFunc ( ButtonBox ) ;
558   glutDialsFunc ( Dials ) ;
559   glutTabletMotionFunc ( TabletMotion ) ;
560   glutTabletButtonFunc ( TabletButton ) ;
561   glutSetKeyRepeat(GLUT_KEY_REPEAT_OFF) ;
562
563   glutIdleFunc ( Idle );
564
565   printf ( "Please enter something to continue: " );
566   fgets ( dummy_string, STRING_LENGTH, stdin );
567
568   glutMainLoop();
569
570   printf ( "Back from the 'freeglut' main loop\n" ) ;
571
572   return 0;             /* ANSI C requires main to return int. */
573 }