Resolution of X11 key-repeat handling
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: https://svn.code.sf.net/p/freeglut/code/trunk@476 7f0cb862-5218-0410-a997-914c9d46530a
This commit is contained in:
parent
a291d1e0d3
commit
6065b3da65
@ -65,7 +65,7 @@ SFG_State fgState = { { -1, -1, GL_FALSE }, /* Position */
|
||||
GL_FALSE, /* UseCurrentContext */
|
||||
GL_FALSE, /* GLDebugSwitch */
|
||||
GL_FALSE, /* XSyncSwitch */
|
||||
GL_FALSE, /* IgnoreKeyRepeat */
|
||||
GL_TRUE, /* KeyRepeat */
|
||||
0xffffffff, /* Modifiers */
|
||||
0, /* FPSInterval */
|
||||
0, /* SwapCount */
|
||||
@ -272,7 +272,7 @@ void fgDeinitialize( void )
|
||||
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;
|
||||
|
@ -233,7 +233,7 @@ struct tagSFG_State
|
||||
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 */
|
||||
@ -367,10 +367,13 @@ struct tagSFG_WindowState
|
||||
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. */
|
||||
|
@ -908,6 +908,34 @@ void FGAPIENTRY glutMainLoopEvent( void )
|
||||
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 );
|
||||
|
@ -93,49 +93,43 @@ void FGAPIENTRY glutReportErrors( void )
|
||||
}
|
||||
|
||||
/*
|
||||
* 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_DEFAULT:
|
||||
{
|
||||
XKeyboardState keyboardState;
|
||||
case GLUT_KEY_REPEAT_OFF:
|
||||
case GLUT_KEY_REPEAT_ON:
|
||||
fgState.KeyRepeat = repeatMode;
|
||||
break;
|
||||
|
||||
XGetKeyboardControl( fgDisplay.Display, &keyboardState );
|
||||
glutSetKeyRepeat(
|
||||
keyboardState.global_auto_repeat == AutoRepeatModeOn ?
|
||||
GLUT_KEY_REPEAT_ON : GLUT_KEY_REPEAT_OFF
|
||||
);
|
||||
}
|
||||
break;
|
||||
case GLUT_KEY_REPEAT_DEFAULT:
|
||||
fgState.KeyRepeat = GLUT_KEY_REPEAT_ON;
|
||||
break;
|
||||
|
||||
default:
|
||||
fgError ("Invalid glutSetKeyRepeat mode: %d", repeatMode);
|
||||
break;
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -542,7 +542,7 @@ int FGAPIENTRY glutDeviceGet( GLenum eWhat )
|
||||
return 0;
|
||||
|
||||
case GLUT_DEVICE_IGNORE_KEY_REPEAT:
|
||||
return fgState.IgnoreKeyRepeat;
|
||||
return fgStructure.Window ? fgStructure.Window->State.IgnoreKeyRepeat : 0;
|
||||
|
||||
case GLUT_DEVICE_KEY_REPEAT:
|
||||
/*
|
||||
|
@ -110,6 +110,9 @@ SFG_Window* fgCreateWindow( SFG_Window* parent, const char* title,
|
||||
|
||||
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.
|
||||
|
Reference in New Issue
Block a user