From 8ec42c1aae4c302083b27cd5ff0162d6b765f8f5 Mon Sep 17 00:00:00 2001 From: mfranz <mfranz> Date: Mon, 12 Nov 2007 19:29:08 +0000 Subject: [PATCH] - move temporary keyboard fix from input.cxx to fg_os{,_sdl}.cxx. This is required to make sure the same letter key gets released, which got the press event. (After Ctrl-press -> a-press -> Ctrl-release a-release we want the Ctrl-a binding released, not the a binding.) - add key listener interface for direct key access from Nasal space --- src/Input/input.cxx | 44 ++++++++++++++++++++++---------------- src/Input/input.hxx | 11 ++++++++++ src/Main/FGManipulator.cxx | 19 ++++++++++++++++ src/Main/FGManipulator.hxx | 1 + src/Main/fg_os.cxx | 15 ++++++++++++- src/Main/fg_os_sdl.cxx | 6 ++---- 6 files changed, 73 insertions(+), 23 deletions(-) diff --git a/src/Input/input.cxx b/src/Input/input.cxx index ca38a2d37..704b25be8 100644 --- a/src/Input/input.cxx +++ b/src/Input/input.cxx @@ -108,7 +108,8 @@ getModAlt () //////////////////////////////////////////////////////////////////////// -FGInput::FGInput () +FGInput::FGInput () : + _key_event(fgGetNode("/devices/status/keyboard/event", true)) { if (default_input == 0) default_input = this; @@ -150,6 +151,13 @@ FGInput::bind () fgTie("/devices/status/keyboard/shift", getModShift); fgTie("/devices/status/keyboard/ctrl", getModCtrl); fgTie("/devices/status/keyboard/alt", getModAlt); + + _key_event->tie("key", SGRawValuePointer<int>(&_key_code)); + _key_event->tie("pressed", SGRawValuePointer<bool>(&_key_pressed)); + _key_event->tie("modifier", SGRawValuePointer<int>(&_key_modifiers)); + _key_event->tie("modifier/shift", SGRawValuePointer<bool>(&_key_shift)); + _key_event->tie("modifier/ctrl", SGRawValuePointer<bool>(&_key_ctrl)); + _key_event->tie("modifier/alt", SGRawValuePointer<bool>(&_key_alt)); } void @@ -158,6 +166,13 @@ FGInput::unbind () fgUntie("/devices/status/keyboard/shift"); fgUntie("/devices/status/keyboard/ctrl"); fgUntie("/devices/status/keyboard/alt"); + + _key_event->untie("key"); + _key_event->untie("pressed"); + _key_event->untie("modifier"); + _key_event->untie("modifier/shift"); + _key_event->untie("modifier/ctrl"); + _key_event->untie("modifier/alt"); } void @@ -204,6 +219,16 @@ FGInput::doKey (int k, int modifiers, int x, int y) return; } + _key_code = k; + _key_modifiers = modifiers & ~KEYMOD_RELEASED; + _key_pressed = bool(!(modifiers & KEYMOD_RELEASED)); + _key_shift = bool(modifiers & KEYMOD_SHIFT); + _key_ctrl = bool(modifiers & KEYMOD_CTRL); + _key_alt = bool(modifiers & KEYMOD_ALT); + _key_event->fireValueChanged(); + if (!_key_code) + return; + button &b = _key_bindings[k]; // Key pressed. @@ -227,23 +252,6 @@ FGInput::doKey (int k, int modifiers, int x, int y) for (unsigned int i = 0; i < bindings.size(); i++) bindings[i]->fire(); b.last_state = 0; - } else { - if (k >= 1 && k <= 26) { - if (_key_bindings[k + '@'].last_state) - doKey(k + '@', KEYMOD_RELEASED, x, y); - if (_key_bindings[k + '`'].last_state) - doKey(k + '`', KEYMOD_RELEASED, x, y); - } else if (k >= 'A' && k <= 'Z') { - if (_key_bindings[k - '@'].last_state) - doKey(k - '@', KEYMOD_RELEASED, x, y); - if (_key_bindings[tolower(k)].last_state) - doKey(tolower(k), KEYMOD_RELEASED, x, y); - } else if (k >= 'a' && k <= 'z') { - if (_key_bindings[k - '`'].last_state) - doKey(k - '`', KEYMOD_RELEASED, x, y); - if (_key_bindings[toupper(k)].last_state) - doKey(toupper(k), KEYMOD_RELEASED, x, y); - } } } } diff --git a/src/Input/input.hxx b/src/Input/input.hxx index a9dd5303f..3b3803e9f 100644 --- a/src/Input/input.hxx +++ b/src/Input/input.hxx @@ -328,6 +328,17 @@ private: * List of currently pressed mouse button events */ std::map<int, std::list<SGSharedPtr<SGPickCallback> > > _activePickCallbacks; + + /** + * Key listener interface. + */ + SGPropertyNode_ptr _key_event; + int _key_code; + int _key_modifiers; + bool _key_pressed; + bool _key_ctrl; + bool _key_alt; + bool _key_shift; }; #endif // _INPUT_HXX diff --git a/src/Main/FGManipulator.cxx b/src/Main/FGManipulator.cxx index 058641981..bf6935de4 100644 --- a/src/Main/FGManipulator.cxx +++ b/src/Main/FGManipulator.cxx @@ -276,5 +276,24 @@ void FGManipulator::handleKey(const osgGA::GUIEventAdapter& ea, int& key, currentModifiers = modifiers; if (eventType == osgGA::GUIEventAdapter::KEYUP) modifiers |= KEYMOD_RELEASED; + + // Release the letter key, for which the keypress was reported + if (key >= 0 && key < int(sizeof(release_keys))) { + if (modifiers & KEYMOD_RELEASED) { + key = release_keys[key]; + } else { + release_keys[key] = key; + if (key >= 1 && key <= 26) { + release_keys[key + '@'] = key; + release_keys[key + '`'] = key; + } else if (key >= 'A' && key <= 'Z') { + release_keys[key - '@'] = key; + release_keys[tolower(key)] = key; + } else if (key >= 'a' && key <= 'z') { + release_keys[key - '`'] = key; + release_keys[toupper(key)] = key; + } + } + } } diff --git a/src/Main/FGManipulator.hxx b/src/Main/FGManipulator.hxx index 4ad190d19..edfcd9f3d 100644 --- a/src/Main/FGManipulator.hxx +++ b/src/Main/FGManipulator.hxx @@ -139,5 +139,6 @@ protected: bool mouseWarped; // workaround for osgViewer double scroll events bool scrollButtonPressed; + int release_keys[128]; }; #endif diff --git a/src/Main/fg_os.cxx b/src/Main/fg_os.cxx index a9fcf86c9..acff231dc 100644 --- a/src/Main/fg_os.cxx +++ b/src/Main/fg_os.cxx @@ -105,15 +105,28 @@ static void GLUTspecialkey(int k, int x, int y) callKeyHandler(256 + k, fgGetKeyModifiers(), x, y); } +static unsigned char release_keys[256]; + static void GLUTkeyup(unsigned char k, int x, int y) { GlutModifiers = glutGetModifiers(); - callKeyHandler(k, fgGetKeyModifiers() | KEYMOD_RELEASED, x, y); + callKeyHandler(release_keys[k], fgGetKeyModifiers() | KEYMOD_RELEASED, x, y); } static void GLUTkey(unsigned char k, int x, int y) { GlutModifiers = glutGetModifiers(); + release_keys[k] = k; + if (k >= 1 && k <= 26) { + release_keys[k + '@'] = k; + release_keys[k + '`'] = k; + } else if (k >= 'A' && k <= 'Z') { + release_keys[k - '@'] = k; + release_keys[tolower(k)] = k; + } else if (k >= 'a' && k <= 'z') { + release_keys[k - '`'] = k; + release_keys[toupper(k)] = k; + } callKeyHandler(k, fgGetKeyModifiers(), x, y); } diff --git a/src/Main/fg_os_sdl.cxx b/src/Main/fg_os_sdl.cxx index 791783207..81f2e4c5a 100644 --- a/src/Main/fg_os_sdl.cxx +++ b/src/Main/fg_os_sdl.cxx @@ -184,10 +184,8 @@ static void handleKey(int key, int raw, int keyup) if(modmask == 0 && KeyHandler) { if (keymod & KEYMOD_RELEASED) { - if (keys[raw].mod) { - key = keys[raw].unicode; - keys[raw].mod = 0; - } + key = keys[raw].unicode; + } else { keys[raw].mod = keymod; keys[raw].unicode = key;