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());