Here you have a patch sent to the ML of ClanLib.
---
Hi,
Old SDL Keyboard behaviour was very strange : when a key was hit and
then release, it looked like it couldn't be released. It was true ! I
saw that ClanLib stored a "last_keycode", and get_keycode(id) just check
if id==last_keycode :-/ I think that it was a joke from Lawouach :
<< Lawouach : well basically this method ensure that we are consistent
as kepp_alive() uses SDL_PollEvent() which get only one event at a time.
This means that between two calls at keep_alive, we can't change this
value but we don't manage any event either. >>
So, I choosed to use a std::map<int, bool> to store keyboard state (only
store keys when are in state "down"). The state is updated at each
CL_InputDevice_SDLKeyboard::handle_keyboard_event. std::list<int> could
be a better solution, because generally only few keys are down in the
same time. What do you think about this ?
See attached patch. I used unified diff, and is in the right way (not my
last patch :-P).
Bye, Haypo
--- cl_cvs2/Sources/SDL/input_device_sdlkeyboard.h 2004-08-24 01:36:59.000000000 +0200
+++ cl_cvs/Sources/SDL/input_device_sdlkeyboard.h 2004-09-20 01:03:54.000000000 +0200
@@ -30,6 +30,7 @@
#include "API/signals.h"
#include <SDL/SDL.h>
+#include <map>
class CL_DisplayWindow_SDL;
@@ -70,7 +71,10 @@
private:
CL_DisplayWindow_SDL *owner;
CL_Slot slot_sdlevent;
- int last_keycode;
+ typedef std::map<int, bool>::iterator state_iterator;
+ typedef std::map<int, bool>::const_iterator state_const_iterator;
+ typedef std::map<int, bool>::value_type state_pair;
+ std::map<int, bool> state;
};
#endif
--- cl_cvs2/Sources/SDL/input_device_sdlkeyboard.cpp 2004-08-24 01:36:59.000000000 +0200
+++ cl_cvs/Sources/SDL/input_device_sdlkeyboard.cpp 2004-09-20 01:03:57.000000000 +0200
@@ -37,7 +37,6 @@
{
type = CL_InputDevice::keyboard;
slot_sdlevent = owner->sig_sdl_keyboard_event.connect(this, &CL_InputDevice_SDLKeyboard::handle_keyboard_event);
- last_keycode = 0;
}
CL_InputDevice_SDLKeyboard::~CL_InputDevice_SDLKeyboard()
@@ -428,9 +427,8 @@
if(!owner->has_focus())
return false;
- // Lawouach : well basically this method ensure that we are consistent as kepp_alive() uses SDL_PollEvent() which get only one event at a time
- // This means that between two calls at keep_alive, we can't change this value but we don't manage any event either
- return (keysym == last_keycode);
+ state_const_iterator pos = state.find (keysym);
+ return (pos != state.end());
}
/////////////////////////////////////////////////////////////////////////////
@@ -921,11 +919,18 @@
if (event.key.type == SDL_KEYDOWN)
{
cl_event.type = CL_InputEvent::pressed;
- last_keycode = cl_event.id;
+
+ state_iterator pos = state.find (cl_event.id);
+ if (pos == state.end()) {
+ state_pair key(cl_event.id, true);
+ state.insert (key);
+ }
}
else if (event.key.type == SDL_KEYUP)
{
cl_event.type = CL_InputEvent::released;
+ state_iterator pos = state.find (cl_event.id);
+ if (pos != state.end()) state.erase(pos);
}
cl_event.device = owner->keyboard;
cl_event.mouse_pos = CL_Point(owner->mouse.get_x(), owner->mouse.get_y());