1
0
Fork 0

- 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
This commit is contained in:
mfranz 2007-11-12 19:29:08 +00:00
parent 5b76cb5409
commit 8ec42c1aae
6 changed files with 73 additions and 23 deletions

View file

@ -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);
}
}
}
}

View file

@ -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

View file

@ -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;
}
}
}
}

View file

@ -139,5 +139,6 @@ protected:
bool mouseWarped;
// workaround for osgViewer double scroll events
bool scrollButtonPressed;
int release_keys[128];
};
#endif

View file

@ -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);
}

View file

@ -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;