glutSetKeyRepeat is global to all FreeGLUT windows in the application
glutIgnoreKeyRepeat is a per-window over-ride
To avoid nasty global X11 state interaction, or GLUT-style
event queue filtering - the approach in FreeGLUT is to
use the current key state XQueryKeymap to detect and
ignore KeyRelease/KeyPress pairs that are auto-generated.
See also:
http://pyopengl.sourceforge.net/documentation/manual/glutSetKeyRepeat.3GLUT.xml
http://pyopengl.sourceforge.net/documentation/manual/glutIgnoreKeyRepeat.3GLUT.xml
git-svn-id: svn+ssh://svn.code.sf.net/p/freeglut/code/trunk/freeglut/freeglut@476
7f0cb862-5218-0410-a997-
914c9d46530a
GL_FALSE, /* UseCurrentContext */
GL_FALSE, /* GLDebugSwitch */
GL_FALSE, /* XSyncSwitch */
- GL_FALSE, /* IgnoreKeyRepeat */
+ GL_TRUE, /* KeyRepeat */
0xffffffff, /* Modifiers */
0, /* FPSInterval */
0, /* SwapCount */
fgState.ActionOnWindowClose = GLUT_ACTION_EXIT;
fgState.ExecState = GLUT_EXEC_STATE_INIT;
- fgState.IgnoreKeyRepeat = GL_TRUE;
+ fgState.KeyRepeat = GL_FALSE;
fgState.Modifiers = 0xffffffff;
fgState.GameModeSize.X = 640;
GLboolean GLDebugSwitch; /* OpenGL state debugging switch */
GLboolean XSyncSwitch; /* X11 sync protocol switch */
- GLboolean IgnoreKeyRepeat; /* Whether to ignore key repeat. */
+ int KeyRepeat; /* Global key repeat mode. */
int Modifiers; /* Current ALT/SHIFT/CTRL state */
GLuint FPSInterval; /* Interval between FPS printfs */
int Cursor; /* The currently selected cursor */
long JoystickPollRate; /* The joystick polling rate */
- long JoystickLastPoll; /* When the last poll has happened */
+ long JoystickLastPoll; /* When the last poll happened */
int MouseX, MouseY; /* The most recent mouse position */
+ GLboolean IgnoreKeyRepeat; /* Whether to ignore key repeat. */
+ GLboolean KeyRepeating; /* Currently in repeat mode */
+
GLboolean IsGameMode; /* Is this the game mode window? */
GLboolean NeedToResize; /* Do we need to resize the window? */
GLboolean IsOffscreen; /* Tags a `window' as on/offscreen. */
GETWINDOW( xkey );
GETMOUSE( xkey );
+ /* Detect auto repeated keys, if configured globally or per-window */
+
+ if ( fgState.KeyRepeat==GLUT_KEY_REPEAT_OFF || window->State.IgnoreKeyRepeat==GL_TRUE )
+ {
+ if (event.type==KeyRelease)
+ {
+ /*
+ * Look at X11 keystate to detect repeat mode.
+ * While X11 says the key is actually held down, we'll ignore KeyRelease/KeyPress pairs.
+ */
+
+ char keys[32];
+ XQueryKeymap( fgDisplay.Display, keys ); /* Look at X11 keystate to detect repeat mode */
+
+ if ( keys[event.xkey.keycode>>3] & (1<<(event.xkey.keycode%8)) )
+ window->State.KeyRepeating = GL_TRUE;
+ else
+ window->State.KeyRepeating = GL_FALSE;
+ }
+ }
+ else
+ window->State.KeyRepeating = GL_FALSE;
+
+ /* Cease processing this event if it is auto repeated */
+
+ if (window->State.KeyRepeating)
+ break;
+
if( event.type == KeyPress )
{
keyboard_cb = FETCH_WCB( *window, Keyboard );
}
/*
- * Turns the ignore key auto repeat feature on and off
- *
- * DEPRECATED 11/4/02 - Do not use
+ * Control the auto-repeat of keystrokes to the current window
*/
void FGAPIENTRY glutIgnoreKeyRepeat( int ignore )
{
- fgState.IgnoreKeyRepeat = ignore ? GL_TRUE : GL_FALSE;
+ freeglut_assert_ready;
+ freeglut_assert_window;
+
+ fgStructure.Window->State.IgnoreKeyRepeat = ignore ? GL_TRUE : GL_FALSE;
}
/*
- * Hints the window system whether to generate key auto repeat, or not.
- * This is evil.
+ * Set global auto-repeat of keystrokes
*
- * XXX Is this also deprecated as of 20021104?
+ * RepeatMode should be either:
+ * GLUT_KEY_REPEAT_OFF
+ * GLUT_KEY_REPEAT_ON
+ * GLUT_KEY_REPEAT_DEFAULT
*/
void FGAPIENTRY glutSetKeyRepeat( int repeatMode )
{
-#if TARGET_HOST_UNIX_X11
-
freeglut_assert_ready;
switch( repeatMode )
{
- case GLUT_KEY_REPEAT_OFF: XAutoRepeatOff( fgDisplay.Display ); break;
- case GLUT_KEY_REPEAT_ON: XAutoRepeatOn( fgDisplay.Display ); break;
+ case GLUT_KEY_REPEAT_OFF:
+ case GLUT_KEY_REPEAT_ON:
+ fgState.KeyRepeat = repeatMode;
+ break;
+
case GLUT_KEY_REPEAT_DEFAULT:
- {
- XKeyboardState keyboardState;
-
- XGetKeyboardControl( fgDisplay.Display, &keyboardState );
- glutSetKeyRepeat(
- keyboardState.global_auto_repeat == AutoRepeatModeOn ?
- GLUT_KEY_REPEAT_ON : GLUT_KEY_REPEAT_OFF
- );
- }
- break;
+ fgState.KeyRepeat = GLUT_KEY_REPEAT_ON;
+ break;
default:
fgError ("Invalid glutSetKeyRepeat mode: %d", repeatMode);
break;
}
-
-#endif
}
/*
return 0;
case GLUT_DEVICE_IGNORE_KEY_REPEAT:
- return fgState.IgnoreKeyRepeat;
+ return fgStructure.Window ? fgStructure.Window->State.IgnoreKeyRepeat : 0;
case GLUT_DEVICE_KEY_REPEAT:
/*
window->IsMenu = isMenu;
+ window->State.IgnoreKeyRepeat = GL_FALSE;
+ window->State.KeyRepeating = GL_FALSE;
+
/*
* Open the window now. The fgOpenWindow() function is system
* dependant, and resides in freeglut_window.c. Uses fgState.