- fgSetWindow( window );
-
- /*
- * Remember the current modifiers state
- */
- modifiers = 0;
- if (event.xkey.state & (ShiftMask|LockMask))
- modifiers |= GLUT_ACTIVE_SHIFT;
- if (event.xkey.state & ControlMask)
- modifiers |= GLUT_ACTIVE_CTRL;
- if (event.xkey.state & Mod1Mask)
- modifiers |= GLUT_ACTIVE_ALT;
- window->State.Modifiers = modifiers;
-
- special_cb( special, event.xkey.x, event.xkey.y );
-
- /*
- * Trash the modifiers state
- */
- window->State.Modifiers = 0xffffffff;
+ keyboard_cb = FETCH_WCB( *window, KeyboardUp );
+ special_cb = FETCH_WCB( *window, SpecialUp );
+ }
+
+ /* Is there a keyboard/special callback hooked for this window? */
+ if( keyboard_cb || special_cb )
+ {
+ XComposeStatus composeStatus;
+ char asciiCode[ 32 ];
+ KeySym keySym;
+ int len;
+
+ /* Check for the ASCII/KeySym codes associated with the event: */
+ len = XLookupString( &event.xkey, asciiCode, sizeof(asciiCode),
+ &keySym, &composeStatus
+ );
+
+ /* GLUT API tells us to have two separate callbacks... */
+ if( len > 0 )
+ {
+ /* ...one for the ASCII translateable keypresses... */
+ if( keyboard_cb )
+ {
+ fgSetWindow( window );
+ fgState.Modifiers = fghGetXModifiers( &event );
+ keyboard_cb( asciiCode[ 0 ],
+ event.xkey.x, event.xkey.y
+ );
+ fgState.Modifiers = 0xffffffff;
+ }
+ }
+ else
+ {
+ int special = -1;
+
+ /*
+ * ...and one for all the others, which need to be
+ * translated to GLUT_KEY_Xs...
+ */
+ switch( keySym )
+ {
+ case XK_F1: special = GLUT_KEY_F1; break;
+ case XK_F2: special = GLUT_KEY_F2; break;
+ case XK_F3: special = GLUT_KEY_F3; break;
+ case XK_F4: special = GLUT_KEY_F4; break;
+ case XK_F5: special = GLUT_KEY_F5; break;
+ case XK_F6: special = GLUT_KEY_F6; break;
+ case XK_F7: special = GLUT_KEY_F7; break;
+ case XK_F8: special = GLUT_KEY_F8; break;
+ case XK_F9: special = GLUT_KEY_F9; break;
+ case XK_F10: special = GLUT_KEY_F10; break;
+ case XK_F11: special = GLUT_KEY_F11; break;
+ case XK_F12: special = GLUT_KEY_F12; break;
+
+ case XK_Left: special = GLUT_KEY_LEFT; break;
+ case XK_Right: special = GLUT_KEY_RIGHT; break;
+ case XK_Up: special = GLUT_KEY_UP; break;
+ case XK_Down: special = GLUT_KEY_DOWN; break;
+
+ case XK_KP_Prior:
+ case XK_Prior: special = GLUT_KEY_PAGE_UP; break;
+ case XK_KP_Next:
+ case XK_Next: special = GLUT_KEY_PAGE_DOWN; break;
+ case XK_KP_Home:
+ case XK_Home: special = GLUT_KEY_HOME; break;
+ case XK_KP_End:
+ case XK_End: special = GLUT_KEY_END; break;
+ case XK_KP_Insert:
+ case XK_Insert: special = GLUT_KEY_INSERT; break;
+ }
+
+ /*
+ * Execute the callback (if one has been specified),
+ * given that the special code seems to be valid...
+ */
+ if( special_cb && (special != -1) )
+ {
+ fgSetWindow( window );
+ fgState.Modifiers = fghGetXModifiers( &event );
+ special_cb( special, event.xkey.x, event.xkey.y );
+ fgState.Modifiers = 0xffffffff;
+ }
+ }