Implemented WaitEvent on Linux

git-svn-id: https://sfml.svn.sourceforge.net/svnroot/sfml/branches/sfml2@1248 4e206d99-4929-0410-ac5d-dfc041789085
This commit is contained in:
laurentgom 2009-10-27 12:26:31 +00:00
parent a68ff5713b
commit 0d66fa1776
2 changed files with 62 additions and 46 deletions

View File

@ -282,54 +282,26 @@ WindowHandle WindowImplX11::GetHandle() const
////////////////////////////////////////////////////////////
void WindowImplX11::ProcessEvents(bool block)
{
// This function implements a workaround to properly discard
// repeated key events when necessary. The problem is that the
// system's key events policy doesn't match SFML's one: X server will generate
// both repeated KeyPress and KeyRelease events when maintaining a key down, while
// SFML only wants repeated KeyPress events. Thus, we have to:
// - Discard duplicated KeyRelease events when EnableKeyRepeat is true
// - Discard both duplicated KeyPress and KeyRelease events when EnableKeyRepeat is false
// Process any event in the queue matching our window
if (block)
{
// Blocking -- wait and process events in the event queue until a valid event is found
XEvent event;
do
{
XIfEvent(myDisplay, &event, &CheckEvent, reinterpret_cast<XPointer>(myWindow));
}
while (!ProcessEvent(event));
}
else
{
// Non-blocking -- process all events in the event queue
XEvent event;
while (XCheckIfEvent(myDisplay, &event, &CheckEvent, reinterpret_cast<XPointer>(myWindow)))
{
// Detect repeated key events
if ((event.type == KeyPress) || (event.type == KeyRelease))
{
if (event.xkey.keycode < 256)
{
// To detect if it is a repeated key event, we check the current state of the key.
// - If the state is "down", KeyReleased events must obviously be discarded.
// - KeyPress events are a little bit harder to handle: they depend on the EnableKeyRepeat state,
// and we need to properly forward the first one.
char keys[32];
XQueryKeymap(myDisplay, keys);
if (keys[event.xkey.keycode >> 3] & (1 << (event.xkey.keycode % 8)))
{
// KeyRelease event + key down = repeated event --> discard
if (event.type == KeyRelease)
{
myLastKeyReleaseEvent = event;
continue;
}
// KeyPress event + key repeat disabled + matching KeyRelease event = repeated event --> discard
if ((event.type == KeyPress) && !myKeyRepeat &&
(myLastKeyReleaseEvent.xkey.keycode == event.xkey.keycode) &&
(myLastKeyReleaseEvent.xkey.time == event.xkey.time))
{
continue;
}
}
}
}
// Process the event
ProcessEvent(event);
}
}
}
////////////////////////////////////////////////////////////
@ -586,8 +558,48 @@ void WindowImplX11::CleanUp()
////////////////////////////////////////////////////////////
void WindowImplX11::ProcessEvent(XEvent windowEvent)
bool WindowImplX11::ProcessEvent(XEvent windowEvent)
{
// This function implements a workaround to properly discard
// repeated key events when necessary. The problem is that the
// system's key events policy doesn't match SFML's one: X server will generate
// both repeated KeyPress and KeyRelease events when maintaining a key down, while
// SFML only wants repeated KeyPress events. Thus, we have to:
// - Discard duplicated KeyRelease events when EnableKeyRepeat is true
// - Discard both duplicated KeyPress and KeyRelease events when EnableKeyRepeat is false
// Detect repeated key events
if ((windowEvent.type == KeyPress) || (windowEvent.type == KeyRelease))
{
if (windowEvent.xkey.keycode < 256)
{
// To detect if it is a repeated key event, we check the current state of the key.
// - If the state is "down", KeyReleased events must obviously be discarded.
// - KeyPress events are a little bit harder to handle: they depend on the EnableKeyRepeat state,
// and we need to properly forward the first one.
char keys[32];
XQueryKeymap(myDisplay, keys);
if (keys[windowEvent.xkey.keycode >> 3] & (1 << (windowEvent.xkey.keycode % 8)))
{
// KeyRelease event + key down = repeated event --> discard
if (windowEvent.type == KeyRelease)
{
myLastKeyReleaseEvent = windowEvent;
return false;
}
// KeyPress event + key repeat disabled + matching KeyRelease event = repeated event --> discard
if ((windowEvent.type == KeyPress) && !myKeyRepeat &&
(myLastKeyReleaseEvent.xkey.keycode == windowEvent.xkey.keycode) &&
(myLastKeyReleaseEvent.xkey.time == windowEvent.xkey.time))
{
return false;
}
}
}
}
// Convert the X11 event to a sf::Event
switch (windowEvent.type)
{
// Destroy event
@ -814,6 +826,8 @@ void WindowImplX11::ProcessEvent(XEvent windowEvent)
break;
}
}
return true;
}

View File

@ -191,8 +191,10 @@ private :
///
/// \param windowEvent Event which has been received
///
/// \return True if the event was processed, false if it was discarded
///
////////////////////////////////////////////////////////////
void ProcessEvent(XEvent windowEvent);
bool ProcessEvent(XEvent windowEvent);
////////////////////////////////////////////////////////////
/// \brief Convert a X11 keysym to SFML key code