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