CallbackMaker.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740
  1. /* CallbackMaker.c */
  2. /*
  3. * Program to invoke all the callbacks that "freeglut" supports
  4. */
  5. #include <GL/freeglut.h>
  6. #include <stdio.h>
  7. #include <stdlib.h>
  8. #include <stdarg.h>
  9. #include <string.h>
  10. static int sequence_number = 0 ;
  11. #define CALLBACKMAKER_N_WINDOWS 4
  12. int windows[CALLBACKMAKER_N_WINDOWS] = {0};
  13. /* define status vars showing whether given callback has been called for given window */
  14. #define CALLBACK_CALLED_VAR(name) int name##_called[CALLBACKMAKER_N_WINDOWS] = {0}
  15. #define CALLBACK_0V(name) int name##_seq[CALLBACKMAKER_N_WINDOWS] = {-1}; CALLBACK_CALLED_VAR(name)
  16. #define CALLBACK_1V(name,field) int name##_##field[CALLBACKMAKER_N_WINDOWS] = {-1}; CALLBACK_0V(name)
  17. #define CALLBACK_2V(name,field1,field2) int name##_##field2[CALLBACKMAKER_N_WINDOWS] = {-1}; CALLBACK_1V(name,field1)
  18. #define CALLBACK_3V(name,field1,field2,field3) int name##_##field3[CALLBACKMAKER_N_WINDOWS] = {-1}; CALLBACK_2V(name,field1,field2)
  19. #define CALLBACK_4V(name,field1,field2,field3,field4) int name##_##field4[CALLBACKMAKER_N_WINDOWS] = {-1}; CALLBACK_3V(name,field1,field2,field3)
  20. #define CALLBACK_5V(name,field1,field2,field3,field4,field5) int name##_##field5[CALLBACKMAKER_N_WINDOWS] = {-1}; CALLBACK_4V(name,field1,field2,field3,field4)
  21. CALLBACK_2V(reshape,width,height);
  22. CALLBACK_2V(position,top,left);
  23. CALLBACK_1V(visibility,vis);
  24. CALLBACK_1V(windowStatus,state);
  25. CALLBACK_4V(key,key,x,y,mod);
  26. CALLBACK_4V(keyup,key,x,y,mod);
  27. CALLBACK_4V(special,key,x,y,mod);
  28. CALLBACK_4V(specialup,key,x,y,mod);
  29. CALLBACK_4V(joystick,a,b,c,d);
  30. CALLBACK_5V(mouse,button,updown,x,y,mod);
  31. CALLBACK_5V(mousewheel,number,direction,x,y,mod);
  32. CALLBACK_3V(motion,x,y,mod);
  33. CALLBACK_3V(passivemotion,x,y,mod);
  34. CALLBACK_1V(entry,state);
  35. CALLBACK_0V(close);
  36. /* menudestroy is registered on each menu, not a window */
  37. int menudestroy_called = 0;
  38. /* menustatus and menustate are global callbacks, set for all menus at the same time */
  39. int menustatus_called = 0;
  40. int menustate_called = 0;
  41. #define STRING_LENGTH 10
  42. static void
  43. bitmapPrintf (const char *fmt, ...)
  44. {
  45. static char buf[256];
  46. va_list args;
  47. va_start(args, fmt);
  48. #if defined(WIN32) && !defined(__CYGWIN__)
  49. (void) _vsnprintf (buf, sizeof(buf), fmt, args);
  50. #else
  51. (void) vsnprintf (buf, sizeof(buf), fmt, args);
  52. #endif
  53. va_end(args);
  54. glutBitmapString ( GLUT_BITMAP_HELVETICA_12, (unsigned char*)buf ) ;
  55. }
  56. static int
  57. getWindowAndIdx(int *winIdx)
  58. {
  59. int window = glutGetWindow();
  60. if (winIdx)
  61. (*winIdx) = window==windows[0] ? 0 :
  62. window==windows[1] ? 1 :
  63. window==windows[2] ? 2 : 3;
  64. return window;
  65. }
  66. static void
  67. Mod2Text(int mods, char *text)
  68. {
  69. if (mods&GLUT_ACTIVE_CTRL)
  70. strcat(text,"CTRL");
  71. if (mods&GLUT_ACTIVE_SHIFT)
  72. {
  73. if (text[0])
  74. strcat(text,"+SHIFT");
  75. else
  76. strcat(text,"SHIFT");
  77. }
  78. if (mods&GLUT_ACTIVE_ALT)
  79. {
  80. if (text[0])
  81. strcat(text,"+ALT");
  82. else
  83. strcat(text,"ALT");
  84. }
  85. if (!text[0])
  86. strcat(text,"none");
  87. }
  88. static void
  89. Display(void)
  90. {
  91. int winIdx;
  92. int window = getWindowAndIdx(&winIdx);
  93. glClear ( GL_COLOR_BUFFER_BIT );
  94. glDisable ( GL_DEPTH_TEST );
  95. glMatrixMode ( GL_PROJECTION );
  96. glPushMatrix();
  97. glLoadIdentity();
  98. glOrtho(0, glutGet ( GLUT_WINDOW_WIDTH ),
  99. 0, glutGet ( GLUT_WINDOW_HEIGHT ), -1, 1 );
  100. glMatrixMode ( GL_MODELVIEW );
  101. glPushMatrix ();
  102. glLoadIdentity ();
  103. glColor3ub ( 0, 0, 0 );
  104. glRasterPos2i ( 10, glutGet ( GLUT_WINDOW_HEIGHT ) - 20 ); /* 10pt margin above 10pt letters */
  105. if ( entry_called[winIdx] )
  106. {
  107. bitmapPrintf ( "Entry %d: %d\n", entry_seq[winIdx], entry_state[winIdx] );
  108. }
  109. if ( visibility_called[winIdx] )
  110. {
  111. bitmapPrintf ( "Visibility %d: %d\n", visibility_seq[winIdx], visibility_vis[winIdx] );
  112. }
  113. if ( windowStatus_called[winIdx] )
  114. {
  115. bitmapPrintf ( "WindowStatus %d: %d\n", windowStatus_seq[winIdx], windowStatus_state[winIdx] );
  116. }
  117. if ( reshape_called[winIdx] )
  118. {
  119. bitmapPrintf ( "Reshape %d: %d %d\n", reshape_seq[winIdx], reshape_width[winIdx], reshape_height[winIdx] );
  120. }
  121. if ( position_called[winIdx] )
  122. {
  123. bitmapPrintf ( "Position %d: %d %d\n", position_seq[winIdx], position_left[winIdx], position_top[winIdx] );
  124. }
  125. if ( key_called[winIdx] )
  126. {
  127. char mods[50] = {0};
  128. Mod2Text(key_mod[winIdx],mods);
  129. bitmapPrintf ( "Key %d: %d(%c) %d %d (mod: %s)\n", key_seq[winIdx], key_key[winIdx], key_key[winIdx], key_x[winIdx], key_y[winIdx], mods );
  130. }
  131. if ( keyup_called[winIdx] )
  132. {
  133. char mods[50] = {0};
  134. Mod2Text(keyup_mod[winIdx],mods);
  135. bitmapPrintf ( "Key Up %d: %d(%c) %d %d (mod: %s)\n", keyup_seq[winIdx], keyup_key[winIdx], keyup_key[winIdx], keyup_x[winIdx], keyup_y[winIdx], mods );
  136. }
  137. if ( special_called[winIdx] )
  138. {
  139. char mods[50] = {0};
  140. Mod2Text(special_mod[winIdx],mods);
  141. bitmapPrintf ( "Special %d: %d(%c) %d %d (mod: %s)\n", special_seq[winIdx], special_key[winIdx], special_key[winIdx], special_x[winIdx], special_y[winIdx], mods );
  142. }
  143. if ( specialup_called[winIdx] )
  144. {
  145. char mods[50] = {0};
  146. Mod2Text(specialup_mod[winIdx],mods);
  147. bitmapPrintf ( "Special Up %d: %d(%c) %d %d (mod: %s)\n", specialup_seq[winIdx], specialup_key[winIdx], specialup_key[winIdx], specialup_x[winIdx], specialup_y[winIdx], mods );
  148. }
  149. if ( joystick_called[winIdx] )
  150. {
  151. bitmapPrintf ( "Joystick %d: %d %d %d %d\n", joystick_seq[winIdx], joystick_a[winIdx], joystick_b[winIdx], joystick_c[winIdx], joystick_d[winIdx] );
  152. }
  153. if ( mouse_called[winIdx] )
  154. {
  155. char mods[50] = {0};
  156. Mod2Text(mouse_mod[winIdx],mods);
  157. bitmapPrintf ( "Mouse %d: %d %d %d %d (mod: %s)\n", mouse_seq[winIdx], mouse_button[winIdx], mouse_updown[winIdx], mouse_x[winIdx], mouse_y[winIdx], mods );
  158. }
  159. if ( mousewheel_called[winIdx] )
  160. {
  161. char mods[50] = {0};
  162. Mod2Text(mousewheel_mod[winIdx],mods);
  163. bitmapPrintf ( "Mouse Wheel %d: %d %d %d %d (mod: %s)\n", mousewheel_seq[winIdx], mousewheel_number[winIdx], mousewheel_direction[winIdx], mousewheel_x[winIdx], mousewheel_y[winIdx], mods );
  164. }
  165. if ( motion_called[winIdx] )
  166. {
  167. char mods[50] = {0};
  168. Mod2Text(motion_mod[winIdx],mods);
  169. bitmapPrintf ( "Motion %d: %d %d (mod: %s)\n", motion_seq[winIdx], motion_x[winIdx], motion_y[winIdx], mods );
  170. }
  171. if ( passivemotion_called[winIdx] )
  172. {
  173. char mods[50] = {0};
  174. Mod2Text(passivemotion_mod[winIdx],mods);
  175. bitmapPrintf ( "Passive Motion %d: %d %d (mod: %s)\n", passivemotion_seq[winIdx], passivemotion_x[winIdx], passivemotion_y[winIdx], mods );
  176. }
  177. glMatrixMode ( GL_PROJECTION );
  178. glPopMatrix ();
  179. glMatrixMode ( GL_MODELVIEW );
  180. glPopMatrix ();
  181. glEnable ( GL_DEPTH_TEST );
  182. printf ( "%6d Window %d Display Callback\n",
  183. ++sequence_number, window ) ;
  184. glutSwapBuffers();
  185. }
  186. static void
  187. Warning(const char *fmt, va_list ap)
  188. {
  189. printf("%6d Warning callback:\n",++sequence_number);
  190. /* print warning message */
  191. vprintf(fmt, ap);
  192. }
  193. static void
  194. Error(const char *fmt, va_list ap)
  195. {
  196. char dummy_string[STRING_LENGTH];
  197. printf("%6d Error callback:\n",++sequence_number);
  198. /* print warning message */
  199. vprintf(fmt, ap);
  200. printf("\n");
  201. /* terminate program, after pause for input so user can see */
  202. printf ( "Please enter something to exit: " );
  203. fgets ( dummy_string, STRING_LENGTH, stdin );
  204. /* Call exit directly as freeglut is messed
  205. * up internally when an error is called.
  206. */
  207. exit(1);
  208. }
  209. static void
  210. Reshape(int width, int height)
  211. {
  212. int winIdx;
  213. int window = getWindowAndIdx(&winIdx);
  214. printf ( "%6d Window %d Reshape Callback: %d %d\n",
  215. ++sequence_number, window, width, height ) ;
  216. reshape_called[winIdx] = 1 ;
  217. reshape_width[winIdx] = width ;
  218. reshape_height[winIdx] = height ;
  219. reshape_seq[winIdx] = sequence_number ;
  220. glViewport(0,0,width,height);
  221. glutPostRedisplay () ;
  222. }
  223. static void
  224. Position(int left, int top)
  225. {
  226. int winIdx;
  227. int window = getWindowAndIdx(&winIdx);
  228. printf ( "%6d Window %d Position Callback: %d %d\n",
  229. ++sequence_number, window, left, top ) ;
  230. position_called[winIdx] = 1 ;
  231. position_left[winIdx] = left ;
  232. position_top[winIdx] = top ;
  233. position_seq[winIdx] = sequence_number ;
  234. glutPostRedisplay () ;
  235. }
  236. static void
  237. Key(unsigned char key, int x, int y)
  238. {
  239. int winIdx;
  240. int window = getWindowAndIdx(&winIdx);
  241. printf ( "%6d Window %d Keyboard Callback: %d %d %d\n",
  242. ++sequence_number, window, key, x, y ) ;
  243. key_called[winIdx] = 1 ;
  244. key_key[winIdx] = key ;
  245. key_x[winIdx] = x ;
  246. key_y[winIdx] = y ;
  247. key_seq[winIdx] = sequence_number ;
  248. key_mod[winIdx] = glutGetModifiers() ;
  249. glutPostRedisplay () ;
  250. }
  251. static void
  252. KeyUp(unsigned char key, int x, int y)
  253. {
  254. int winIdx;
  255. int window = getWindowAndIdx(&winIdx);
  256. printf ( "%6d Window %d Key Release Callback: %d %d %d\n",
  257. ++sequence_number, window, key, x, y ) ;
  258. keyup_called[winIdx] = 1 ;
  259. keyup_key[winIdx] = key ;
  260. keyup_x[winIdx] = x ;
  261. keyup_y[winIdx] = y ;
  262. keyup_seq[winIdx] = sequence_number ;
  263. keyup_mod[winIdx] = glutGetModifiers() ;
  264. glutPostRedisplay () ;
  265. }
  266. static void
  267. Special(int key, int x, int y)
  268. {
  269. int winIdx;
  270. int window = getWindowAndIdx(&winIdx);
  271. printf ( "%6d Window %d Special Key Callback: %d %d %d\n",
  272. ++sequence_number, window, key, x, y ) ;
  273. special_called[winIdx] = 1 ;
  274. special_key[winIdx] = key ;
  275. special_x[winIdx] = x ;
  276. special_y[winIdx] = y ;
  277. special_seq[winIdx] = sequence_number ;
  278. special_mod[winIdx] = glutGetModifiers() ;
  279. glutPostRedisplay () ;
  280. }
  281. static void
  282. SpecialUp(int key, int x, int y)
  283. {
  284. int winIdx;
  285. int window = getWindowAndIdx(&winIdx);
  286. printf ( "%6d Window %d Special Key Release Callback: %d %d %d\n",
  287. ++sequence_number, window, key, x, y ) ;
  288. specialup_called[winIdx] = 1 ;
  289. specialup_key[winIdx] = key ;
  290. specialup_x[winIdx] = x ;
  291. specialup_y[winIdx] = y ;
  292. specialup_seq[winIdx] = sequence_number ;
  293. specialup_mod[winIdx] = glutGetModifiers() ;
  294. glutPostRedisplay () ;
  295. }
  296. static void
  297. Joystick( unsigned int a, int b, int c, int d) /* Need meaningful names */
  298. {
  299. int winIdx;
  300. int window = getWindowAndIdx(&winIdx);
  301. printf ( "%6d Window %d Joystick Callback: %d %d %d %d\n",
  302. ++sequence_number, window, a, b, c, d ) ;
  303. joystick_called[winIdx] = 1 ;
  304. joystick_a[winIdx] = a ;
  305. joystick_b[winIdx] = b ;
  306. joystick_c[winIdx] = c ;
  307. joystick_d[winIdx] = d ;
  308. joystick_seq[winIdx] = sequence_number ;
  309. glutPostRedisplay () ;
  310. }
  311. static void
  312. Mouse(int button, int updown, int x, int y)
  313. {
  314. int winIdx;
  315. int window = getWindowAndIdx(&winIdx);
  316. printf ( "%6d Window %d Mouse Click Callback: %d %d %d %d\n",
  317. ++sequence_number, window, button, updown, x, y ) ;
  318. mouse_called[winIdx] = 1 ;
  319. mouse_button[winIdx] = button ;
  320. mouse_updown[winIdx] = updown ;
  321. mouse_x[winIdx] = x ;
  322. mouse_y[winIdx] = y ;
  323. mouse_seq[winIdx] = sequence_number ;
  324. mouse_mod[winIdx] = glutGetModifiers() ;
  325. glutPostRedisplay () ;
  326. }
  327. static void
  328. MouseWheel(int wheel_number, int direction, int x, int y)
  329. {
  330. int winIdx;
  331. int window = getWindowAndIdx(&winIdx);
  332. printf ( "%6d Window %d Mouse Wheel Callback: %d %d %d %d\n",
  333. ++sequence_number, window, wheel_number, direction, x, y ) ;
  334. mousewheel_called[winIdx] = 1 ;
  335. mousewheel_number[winIdx] = wheel_number ;
  336. mousewheel_direction[winIdx] = direction ;
  337. mousewheel_x[winIdx] = x ;
  338. mousewheel_y[winIdx] = y ;
  339. mousewheel_seq[winIdx] = sequence_number ;
  340. mousewheel_mod[winIdx] = glutGetModifiers() ;
  341. glutPostRedisplay () ;
  342. }
  343. static void
  344. Motion(int x, int y)
  345. {
  346. int winIdx;
  347. int window = getWindowAndIdx(&winIdx);
  348. printf ( "%6d Window %d Mouse Motion Callback: %d %d\n",
  349. ++sequence_number, window, x, y ) ;
  350. motion_called[winIdx] = 1 ;
  351. motion_x[winIdx] = x ;
  352. motion_y[winIdx] = y ;
  353. motion_seq[winIdx] = sequence_number ;
  354. motion_mod[winIdx] = glutGetModifiers() ;
  355. glutPostRedisplay () ;
  356. }
  357. static void
  358. PassiveMotion(int x, int y)
  359. {
  360. int winIdx;
  361. int window = getWindowAndIdx(&winIdx);
  362. printf ( "%6d Window %d Mouse Passive Motion Callback: %d %d\n",
  363. ++sequence_number, window, x, y ) ;
  364. passivemotion_called[winIdx] = 1 ;
  365. passivemotion_x[winIdx] = x ;
  366. passivemotion_y[winIdx] = y ;
  367. passivemotion_seq[winIdx] = sequence_number ;
  368. passivemotion_mod[winIdx] = glutGetModifiers() ;
  369. glutPostRedisplay () ;
  370. }
  371. static void
  372. Entry(int state)
  373. {
  374. int winIdx;
  375. int window = getWindowAndIdx(&winIdx);
  376. printf ( "%6d Window %d Entry Callback: %d\n",
  377. ++sequence_number, window, state ) ;
  378. entry_called[winIdx] = 1 ;
  379. entry_seq[winIdx] = sequence_number;
  380. entry_state[winIdx] = state;
  381. glutPostRedisplay () ;
  382. }
  383. static void
  384. Close(void)
  385. {
  386. int window = getWindowAndIdx(NULL);
  387. printf ( "%6d Window %d Close Callback\n",
  388. ++sequence_number, window ) ;
  389. }
  390. static void
  391. OverlayDisplay(void)
  392. {
  393. int window = getWindowAndIdx(NULL);
  394. printf ( "%6d Window %d OverlayDisplay Callback\n",
  395. ++sequence_number, window ) ;
  396. glutPostRedisplay () ;
  397. }
  398. static void
  399. Visibility(int vis)
  400. {
  401. int winIdx;
  402. int window = getWindowAndIdx(&winIdx);
  403. printf ( "%6d Window %d Visibility Callback: %d\n",
  404. ++sequence_number, window, vis ) ;
  405. visibility_called[winIdx] = 1 ;
  406. visibility_vis[winIdx] = vis ;
  407. visibility_seq[winIdx] = sequence_number ;
  408. glutPostRedisplay () ;
  409. }
  410. static void
  411. WindowStatus(int state)
  412. {
  413. int winIdx;
  414. int window = getWindowAndIdx(&winIdx);
  415. printf ( "%6d Window %d WindowStatus Callback: %d\n",
  416. ++sequence_number, window, state ) ;
  417. windowStatus_called[winIdx] = 1 ;
  418. windowStatus_state[winIdx] = state ;
  419. windowStatus_seq[winIdx] = sequence_number ;
  420. glutPostRedisplay () ;
  421. }
  422. static void
  423. SpaceMotion(int x, int y, int z)
  424. {
  425. int window = getWindowAndIdx(NULL);
  426. printf ( "%6d Window %d SpaceMotion Callback: %d %d %d\n",
  427. ++sequence_number, window, x, y, z ) ;
  428. glutPostRedisplay () ;
  429. }
  430. static void
  431. SpaceRotation(int x, int y, int z)
  432. {
  433. int window = getWindowAndIdx(NULL);
  434. printf ( "%6d Window %d SpaceRotation Callback: %d %d %d\n",
  435. ++sequence_number, window, x, y, z ) ;
  436. glutPostRedisplay () ;
  437. }
  438. static void
  439. SpaceButton(int button, int updown)
  440. {
  441. int window = getWindowAndIdx(NULL);
  442. printf ( "%6d Window %d SpaceButton Callback: %d %d\n",
  443. ++sequence_number, window, button, updown ) ;
  444. glutPostRedisplay () ;
  445. }
  446. static void
  447. Dials(int x, int y)
  448. {
  449. int window = getWindowAndIdx(NULL);
  450. printf ( "%6d Window %d Dials Callback: %d %d\n",
  451. ++sequence_number, window, x, y ) ;
  452. glutPostRedisplay () ;
  453. }
  454. static void
  455. ButtonBox(int button, int updown)
  456. {
  457. int window = getWindowAndIdx(NULL);
  458. printf ( "%6d Window %d ButtonBox Callback: %d %d\n",
  459. ++sequence_number, window, button, updown ) ;
  460. glutPostRedisplay () ;
  461. }
  462. static void
  463. TabletMotion(int x, int y)
  464. {
  465. int window = getWindowAndIdx(NULL);
  466. printf ( "%6d Window %d TabletMotion Callback: %d %d\n",
  467. ++sequence_number, window, x, y ) ;
  468. glutPostRedisplay () ;
  469. }
  470. static void
  471. TabletButton(int button, int updown, int x, int y)
  472. {
  473. int window = getWindowAndIdx(NULL);
  474. printf ( "%6d Window %d TabletButton Callback: %d %d %d %d\n",
  475. ++sequence_number, window, button, updown, x, y ) ;
  476. glutPostRedisplay () ;
  477. }
  478. static void
  479. MenuCallback ( int value )
  480. {
  481. int menu = glutGetMenu();
  482. int window = getWindowAndIdx(NULL);
  483. printf( "%6d Menu %d MenuCallback for menu opened in Window %d - value is %d\n",
  484. ++sequence_number, menu, window, value );
  485. }
  486. static void
  487. MenuDestroy( void )
  488. {
  489. int menu = glutGetMenu();
  490. menudestroy_called = 1 ;
  491. printf ( "%6d Menu %d MenuDestroy Callback\n",
  492. ++sequence_number, menu ) ;
  493. }
  494. static void
  495. MenuStatus( int status, int x, int y )
  496. {
  497. /* Menu and window for which this event is triggered are current when the callback is called */
  498. int menu = glutGetMenu();
  499. int window = getWindowAndIdx(NULL);
  500. menustatus_called = 1 ;
  501. printf ( "%6d Menu %d MenuStatus Callback in Window %d: %d %d %d\n",
  502. ++sequence_number, menu, window, status, x, y ) ;
  503. glutPostRedisplay () ;
  504. }
  505. static void
  506. MenuState( int status )
  507. {
  508. /* Menu and window for which this event is triggered are current when the callback is called */
  509. int menu = glutGetMenu();
  510. int window = getWindowAndIdx(NULL);
  511. menustate_called = 1 ;
  512. printf ( "%6d Menu %d MenuState Callback in Window %d: %d\n",
  513. ++sequence_number, menu, window, status) ;
  514. glutPostRedisplay () ;
  515. }
  516. static void Idle ( void )
  517. {
  518. ++sequence_number ;
  519. }
  520. static void SetWindowCallbacks( int first )
  521. {
  522. /* All these callbacks are set for only the current window */
  523. glutDisplayFunc( Display );
  524. glutReshapeFunc( Reshape );
  525. glutPositionFunc( Position );
  526. glutKeyboardFunc( Key );
  527. glutSpecialFunc( Special );
  528. glutKeyboardUpFunc( KeyUp );
  529. glutSpecialUpFunc( SpecialUp );
  530. if (first)
  531. glutJoystickFunc( Joystick, 100 );
  532. glutMouseFunc ( Mouse ) ;
  533. glutMouseWheelFunc ( MouseWheel ) ;
  534. glutMotionFunc ( Motion ) ;
  535. glutPassiveMotionFunc ( PassiveMotion ) ;
  536. glutEntryFunc ( Entry ) ;
  537. glutCloseFunc ( Close ) ;
  538. glutOverlayDisplayFunc ( OverlayDisplay ) ;
  539. glutSpaceballMotionFunc ( SpaceMotion ) ;
  540. glutSpaceballRotateFunc ( SpaceRotation ) ;
  541. glutSpaceballButtonFunc ( SpaceButton ) ;
  542. glutButtonBoxFunc ( ButtonBox ) ;
  543. glutDialsFunc ( Dials ) ;
  544. glutTabletMotionFunc ( TabletMotion ) ;
  545. glutTabletButtonFunc ( TabletButton ) ;
  546. /* glutVisibilityFunc is deprecated in favor of glutWindowStatusFunc, which provides more detail.
  547. * Setting one of these overwrites the other (see docs).
  548. */
  549. glutVisibilityFunc ( Visibility ); /* This will thus never be called, as glutWindowStatusFunc is set afterwards */
  550. glutWindowStatusFunc ( WindowStatus ) ;
  551. }
  552. int
  553. main(int argc, char *argv[])
  554. {
  555. char dummy_string[STRING_LENGTH];
  556. int menuID, subMenuA, subMenuB;
  557. glutInitWarningFunc(Warning);
  558. glutInitErrorFunc(Error);
  559. glutInitWindowSize(500, 250);
  560. glutInitWindowPosition ( 140, 140 );
  561. glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE );
  562. glutInit(&argc, argv);
  563. /* global setting: mainloop does not return when a window is closed, only returns when all windows are closed */
  564. glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE,GLUT_ACTION_CONTINUE_EXECUTION);
  565. /* global setting: repeated keys generating by keeping the key pressed down are passed on to the keyboard callback */
  566. /* There are two functions to control this behavior, glutSetKeyRepeat to set it globally, and glutIgnoreKeyRepeat to set it per window.
  567. * These two interact however. If key repeat is globally switched off (glutSetKeyRepeat(GLUT_KEY_REPEAT_OFF)), it cannot be overridden
  568. * (switched back on) for a specific window with glutIgnoreKeyRepeat. However, if key repeat is globally switched on
  569. * (glutSetKeyRepeat(GLUT_KEY_REPEAT_ON)), it can be overridden (switched off) with glutIgnoreKeyRepeat on a per-window basis. That is
  570. * what we demonstrate here.
  571. */
  572. glutSetKeyRepeat(GLUT_KEY_REPEAT_ON);
  573. /* Set other global callback (global as in not associated with any specific menu or window) */
  574. glutIdleFunc ( Idle );
  575. glutMenuStatusFunc ( MenuStatus );
  576. glutMenuStateFunc ( MenuState ); /* Note that glutMenuStatusFunc is an enhanced version of the deprecated glutMenuStateFunc. */
  577. /* Open first window */
  578. windows[0] = glutCreateWindow( "Callback Demo" );
  579. printf ( "Creating window %d as 'Callback Demo'\n", windows[0] ) ;
  580. glClearColor(1.0, 1.0, 1.0, 1.0);
  581. /* callbacks, settings and menus for this window */
  582. SetWindowCallbacks( 1 );
  583. glutIgnoreKeyRepeat(GL_TRUE);
  584. glutSetIconTitle("Icon Test - Callback Demo");
  585. subMenuA = glutCreateMenu( MenuCallback );
  586. glutAddMenuEntry( "Sub menu A1 (01)", 11 );
  587. glutAddMenuEntry( "Sub menu A2 (02)", 12 );
  588. glutAddMenuEntry( "Sub menu A3 (03)", 13 );
  589. glutMenuDestroyFunc ( MenuDestroy ); /* callback specific to this menu */
  590. /* Change font for this menu */
  591. glutSetMenuFont(subMenuA, GLUT_BITMAP_HELVETICA_12);
  592. subMenuB = glutCreateMenu( MenuCallback );
  593. glutAddMenuEntry( "Sub menu B1 (04)", 14 );
  594. glutAddMenuEntry( "Sub menu B2 (05)", 15 );
  595. glutAddMenuEntry( "Sub menu B3 (06)", 16 );
  596. glutAddSubMenu( "Going to sub menu A", subMenuA );
  597. glutMenuDestroyFunc ( MenuDestroy ); /* callback specific to this menu */
  598. glutSetMenuFont(subMenuB, GLUT_BITMAP_9_BY_15);
  599. menuID = glutCreateMenu( MenuCallback );
  600. glutAddMenuEntry( "Entry one", 21 );
  601. glutAddMenuEntry( "Entry two", 22 );
  602. glutAddMenuEntry( "Entry three", 23 );
  603. glutAddMenuEntry( "Entry four", 24 );
  604. glutAddMenuEntry( "Entry five", 25 );
  605. glutAddSubMenu( "Enter sub menu A", subMenuA );
  606. glutAddSubMenu( "Enter sub menu B", subMenuB );
  607. glutMenuDestroyFunc ( MenuDestroy ); /* callback specific to this menu */
  608. glutAttachMenu( GLUT_LEFT_BUTTON );
  609. /* Position second window right next to the first */
  610. glutInitWindowPosition ( 140+500+2*glutGet(GLUT_WINDOW_BORDER_WIDTH), 140 );
  611. glutInitWindowSize(600, 600);
  612. windows[1] = glutCreateWindow( "Second Window" );
  613. printf ( "Creating window %d as 'Second Window'\n", windows[1] ) ;
  614. glClearColor(1.0, 1.0, 1.0, 1.0);
  615. /* callbacks, settings and menus for this window */
  616. SetWindowCallbacks( 0 );
  617. glutIgnoreKeyRepeat(GL_TRUE);
  618. glutSetMenu(subMenuB);
  619. glutAttachMenu( GLUT_RIGHT_BUTTON );
  620. /* position a third window as a subwindow of the second */
  621. windows[2] = glutCreateSubWindow(windows[1],0,300,600,300);
  622. printf ( "Creating window %d as subwindow to 'Second Window'\n", windows[2] ) ;
  623. glClearColor(0.7f, 0.7f, 0.7f, 1.0);
  624. /* callbacks, settings and menus for this window */
  625. SetWindowCallbacks( 0 );
  626. glutSetCursor(GLUT_CURSOR_CROSSHAIR); /* Cursors are per window */
  627. glutSetMenu(subMenuA);
  628. glutAttachMenu( GLUT_RIGHT_BUTTON );
  629. /* position a fourth window as a subsubwindow (grandchild) of the second */
  630. windows[3] = glutCreateSubWindow(windows[2],300,0,300,300);
  631. printf ( "Creating window %d as subsubwindow to 'Second Window'\n", windows[3] ) ;
  632. glClearColor(0.4f, 0.4f, 0.4f, 1.0);
  633. /* callbacks and menus for this window */
  634. SetWindowCallbacks( 0 );
  635. glutSetCursor(GLUT_CURSOR_INHERIT); /* Inherit cursor look from parent (this is default on window creation) - comment the below to see in action */
  636. glutSetCursor(GLUT_CURSOR_CYCLE);
  637. printf ( "Please enter something to continue: " );
  638. fgets ( dummy_string, STRING_LENGTH, stdin );
  639. glutMainLoop();
  640. printf ( "Back from the 'freeglut' main loop\n" ) ;
  641. return EXIT_SUCCESS;
  642. }