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, /* UseCurrentContext */
|
||||||
GL_FALSE, /* GLDebugSwitch */
|
GL_FALSE, /* GLDebugSwitch */
|
||||||
GL_FALSE, /* XSyncSwitch */
|
GL_FALSE, /* XSyncSwitch */
|
||||||
GL_FALSE, /* IgnoreKeyRepeat */
|
GL_TRUE, /* KeyRepeat */
|
||||||
0xffffffff, /* Modifiers */
|
0xffffffff, /* Modifiers */
|
||||||
0, /* FPSInterval */
|
0, /* FPSInterval */
|
||||||
0, /* SwapCount */
|
0, /* SwapCount */
|
||||||
@ -272,7 +272,7 @@ void fgDeinitialize( void )
|
|||||||
fgState.ActionOnWindowClose = GLUT_ACTION_EXIT;
|
fgState.ActionOnWindowClose = GLUT_ACTION_EXIT;
|
||||||
fgState.ExecState = GLUT_EXEC_STATE_INIT;
|
fgState.ExecState = GLUT_EXEC_STATE_INIT;
|
||||||
|
|
||||||
fgState.IgnoreKeyRepeat = GL_TRUE;
|
fgState.KeyRepeat = GL_FALSE;
|
||||||
fgState.Modifiers = 0xffffffff;
|
fgState.Modifiers = 0xffffffff;
|
||||||
|
|
||||||
fgState.GameModeSize.X = 640;
|
fgState.GameModeSize.X = 640;
|
||||||
|
@ -233,7 +233,7 @@ struct tagSFG_State
|
|||||||
GLboolean GLDebugSwitch; /* OpenGL state debugging switch */
|
GLboolean GLDebugSwitch; /* OpenGL state debugging switch */
|
||||||
GLboolean XSyncSwitch; /* X11 sync protocol 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 */
|
int Modifiers; /* Current ALT/SHIFT/CTRL state */
|
||||||
|
|
||||||
GLuint FPSInterval; /* Interval between FPS printfs */
|
GLuint FPSInterval; /* Interval between FPS printfs */
|
||||||
@ -367,10 +367,13 @@ struct tagSFG_WindowState
|
|||||||
int Cursor; /* The currently selected cursor */
|
int Cursor; /* The currently selected cursor */
|
||||||
|
|
||||||
long JoystickPollRate; /* The joystick polling rate */
|
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 */
|
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 IsGameMode; /* Is this the game mode window? */
|
||||||
GLboolean NeedToResize; /* Do we need to resize the window? */
|
GLboolean NeedToResize; /* Do we need to resize the window? */
|
||||||
GLboolean IsOffscreen; /* Tags a `window' as on/offscreen. */
|
GLboolean IsOffscreen; /* Tags a `window' as on/offscreen. */
|
||||||
|
@ -908,6 +908,34 @@ void FGAPIENTRY glutMainLoopEvent( void )
|
|||||||
GETWINDOW( xkey );
|
GETWINDOW( xkey );
|
||||||
GETMOUSE( 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 )
|
if( event.type == KeyPress )
|
||||||
{
|
{
|
||||||
keyboard_cb = FETCH_WCB( *window, Keyboard );
|
keyboard_cb = FETCH_WCB( *window, Keyboard );
|
||||||
|
@ -93,49 +93,43 @@ void FGAPIENTRY glutReportErrors( void )
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Turns the ignore key auto repeat feature on and off
|
* Control the auto-repeat of keystrokes to the current window
|
||||||
*
|
|
||||||
* DEPRECATED 11/4/02 - Do not use
|
|
||||||
*/
|
*/
|
||||||
void FGAPIENTRY glutIgnoreKeyRepeat( int ignore )
|
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.
|
* Set global auto-repeat of keystrokes
|
||||||
* This is evil.
|
|
||||||
*
|
*
|
||||||
* 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 )
|
void FGAPIENTRY glutSetKeyRepeat( int repeatMode )
|
||||||
{
|
{
|
||||||
#if TARGET_HOST_UNIX_X11
|
|
||||||
|
|
||||||
freeglut_assert_ready;
|
freeglut_assert_ready;
|
||||||
|
|
||||||
switch( repeatMode )
|
switch( repeatMode )
|
||||||
{
|
{
|
||||||
case GLUT_KEY_REPEAT_OFF: XAutoRepeatOff( fgDisplay.Display ); break;
|
case GLUT_KEY_REPEAT_OFF:
|
||||||
case GLUT_KEY_REPEAT_ON: XAutoRepeatOn( fgDisplay.Display ); break;
|
case GLUT_KEY_REPEAT_ON:
|
||||||
case GLUT_KEY_REPEAT_DEFAULT:
|
fgState.KeyRepeat = repeatMode;
|
||||||
{
|
break;
|
||||||
XKeyboardState keyboardState;
|
|
||||||
|
|
||||||
XGetKeyboardControl( fgDisplay.Display, &keyboardState );
|
case GLUT_KEY_REPEAT_DEFAULT:
|
||||||
glutSetKeyRepeat(
|
fgState.KeyRepeat = GLUT_KEY_REPEAT_ON;
|
||||||
keyboardState.global_auto_repeat == AutoRepeatModeOn ?
|
break;
|
||||||
GLUT_KEY_REPEAT_ON : GLUT_KEY_REPEAT_OFF
|
|
||||||
);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
fgError ("Invalid glutSetKeyRepeat mode: %d", repeatMode);
|
fgError ("Invalid glutSetKeyRepeat mode: %d", repeatMode);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -542,7 +542,7 @@ int FGAPIENTRY glutDeviceGet( GLenum eWhat )
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
case GLUT_DEVICE_IGNORE_KEY_REPEAT:
|
case GLUT_DEVICE_IGNORE_KEY_REPEAT:
|
||||||
return fgState.IgnoreKeyRepeat;
|
return fgStructure.Window ? fgStructure.Window->State.IgnoreKeyRepeat : 0;
|
||||||
|
|
||||||
case GLUT_DEVICE_KEY_REPEAT:
|
case GLUT_DEVICE_KEY_REPEAT:
|
||||||
/*
|
/*
|
||||||
|
@ -110,6 +110,9 @@ SFG_Window* fgCreateWindow( SFG_Window* parent, const char* title,
|
|||||||
|
|
||||||
window->IsMenu = isMenu;
|
window->IsMenu = isMenu;
|
||||||
|
|
||||||
|
window->State.IgnoreKeyRepeat = GL_FALSE;
|
||||||
|
window->State.KeyRepeating = GL_FALSE;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Open the window now. The fgOpenWindow() function is system
|
* Open the window now. The fgOpenWindow() function is system
|
||||||
* dependant, and resides in freeglut_window.c. Uses fgState.
|
* dependant, and resides in freeglut_window.c. Uses fgState.
|
||||||
|
Reference in New Issue
Block a user