# include <config.h>
#endif
-#ifdef HAVE_WINDOWS_H
-# include <windows.h>
-#endif
-
#include <simgear/compiler.h>
#include <math.h>
#include <ctype.h>
+#include <sstream>
-#include STL_FSTREAM
-#include STL_STRING
+#include <fstream>
+#include <string>
#include <vector>
#include <simgear/compiler.h>
#include <Main/renderer.hxx>
SG_USING_STD(ifstream);
+SG_USING_STD(ostringstream);
SG_USING_STD(string);
SG_USING_STD(vector);
// Local functions.
////////////////////////////////////////////////////////////////////////
+static int
+getModifiers ()
+{
+ return fgGetKeyModifiers() >> 1;
+}
+
static bool
getModShift ()
{
return bool(fgGetKeyModifiers() & KEYMOD_ALT);
}
+static bool
+getModMeta ()
+{
+ return bool(fgGetKeyModifiers() & KEYMOD_META);
+}
+
+static bool
+getModSuper ()
+{
+ return bool(fgGetKeyModifiers() & KEYMOD_SUPER);
+}
+
+static bool
+getModHyper ()
+{
+ return bool(fgGetKeyModifiers() & KEYMOD_HYPER);
+}
+
\f
////////////////////////////////////////////////////////////////////////
// Implementation of FGInput.
////////////////////////////////////////////////////////////////////////
-FGInput::FGInput ()
+FGInput::FGInput () :
+ _key_event(fgGetNode("/devices/status/keyboard/event", true))
{
if (default_input == 0)
default_input = this;
void
FGInput::init ()
{
- _init_keyboard();
_init_joystick();
_init_mouse();
FGInput::postinit ()
{
_postinit_joystick();
+ _postinit_keyboard();
}
void
FGInput::bind ()
{
+ fgTie("/devices/status/keyboard", getModifiers);
fgTie("/devices/status/keyboard/shift", getModShift);
fgTie("/devices/status/keyboard/ctrl", getModCtrl);
fgTie("/devices/status/keyboard/alt", getModAlt);
+ fgTie("/devices/status/keyboard/meta", getModMeta);
+ fgTie("/devices/status/keyboard/super", getModSuper);
+ fgTie("/devices/status/keyboard/hyper", getModHyper);
+
+ _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));
+ _key_event->tie("modifier/meta", SGRawValuePointer<bool>(&_key_meta));
+ _key_event->tie("modifier/super", SGRawValuePointer<bool>(&_key_super));
+ _key_event->tie("modifier/hyper", SGRawValuePointer<bool>(&_key_hyper));
}
void
FGInput::unbind ()
{
+ fgUntie("/devices/status/keyboard");
fgUntie("/devices/status/keyboard/shift");
fgUntie("/devices/status/keyboard/ctrl");
fgUntie("/devices/status/keyboard/alt");
+ fgUntie("/devices/status/keyboard/meta");
+ fgUntie("/devices/status/keyboard/super");
+ fgUntie("/devices/status/keyboard/hyper");
+
+ _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");
+ _key_event->untie("modifier/meta");
+ _key_event->untie("modifier/super");
+ _key_event->untie("modifier/hyper");
}
void
return;
}
+ _key_code = k;
+ _key_modifiers = modifiers >> 1;
+ _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_meta = bool(modifiers & KEYMOD_META);
+ _key_super = bool(modifiers & KEYMOD_SUPER);
+ _key_hyper = bool(modifiers & KEYMOD_HYPER);
+ _key_event->fireValueChanged();
+ if (_key_code < 0)
+ return;
+
+ k = _key_code;
+ modifiers = _key_modifiers << 1;
+ if (!_key_pressed)
+ modifiers |= KEYMOD_RELEASED;
button &b = _key_bindings[k];
// Key pressed.
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);
- }
}
}
}
}
if (mode.pass_through) {
- // The pu stuff seems to need that. May be it does opengl picking ...
- fgMakeCurrent();
if (0 <= x && 0 <= y && puMouse(b, updown, x, y))
return;
else if (0 <= x && 0 <= y && (globals->get_current_panel() != 0) &&
fgSetInt("/devices/status/mice/mouse/y", m.y = y);
}
-void
-FGInput::_init_keyboard ()
-{
- SG_LOG(SG_INPUT, SG_DEBUG, "Initializing key bindings");
- _module[0] = 0;
- SGPropertyNode * key_nodes = fgGetNode("/input/keyboard");
- if (key_nodes == 0) {
- SG_LOG(SG_INPUT, SG_WARN, "No key bindings (/input/keyboard)!!");
- key_nodes = fgGetNode("/input/keyboard", true);
- }
-
- vector<SGPropertyNode_ptr> keys = key_nodes->getChildren("key");
- for (unsigned int i = 0; i < keys.size(); i++) {
- int index = keys[i]->getIndex();
- SG_LOG(SG_INPUT, SG_DEBUG, "Binding key " << index);
-
- _key_bindings[index].bindings->clear();
- _key_bindings[index].is_repeatable = keys[i]->getBoolValue("repeatable");
- _key_bindings[index].last_state = 0;
- _read_bindings(keys[i], _key_bindings[index].bindings, KEYMOD_NONE);
- }
-}
-
void
FGInput::_scan_joystick_dir(SGPath *path, SGPropertyNode* node, int *index)
}
+void
+FGInput::_postinit_keyboard()
+{
+ SG_LOG(SG_INPUT, SG_DEBUG, "Initializing key bindings");
+ _module = "__kbd";
+ SGPropertyNode * key_nodes = fgGetNode("/input/keyboard");
+ if (key_nodes == 0) {
+ SG_LOG(SG_INPUT, SG_WARN, "No key bindings (/input/keyboard)!!");
+ key_nodes = fgGetNode("/input/keyboard", true);
+ }
+
+ FGNasalSys *nasalsys = (FGNasalSys *)globals->get_subsystem("nasal");
+ vector<SGPropertyNode_ptr> nasal = key_nodes->getChildren("nasal");
+ for (unsigned int j = 0; j < nasal.size(); j++) {
+ nasal[j]->setStringValue("module", _module.c_str());
+ nasalsys->handleCommand(nasal[j]);
+ }
+
+ vector<SGPropertyNode_ptr> keys = key_nodes->getChildren("key");
+ for (unsigned int i = 0; i < keys.size(); i++) {
+ int index = keys[i]->getIndex();
+ SG_LOG(SG_INPUT, SG_DEBUG, "Binding key " << index);
+
+ _key_bindings[index].bindings->clear();
+ _key_bindings[index].is_repeatable = keys[i]->getBoolValue("repeatable");
+ _key_bindings[index].last_state = 0;
+ _read_bindings(keys[i], _key_bindings[index].bindings, KEYMOD_NONE);
+ }
+}
+
+
void
FGInput::_postinit_joystick()
{
//
// Initialize nasal groups.
//
- string init;
- init = "this=\"" + string(js_node->getPath()) + "\"";
- sprintf(_module, "__js%d", i);
- nasalsys->createModule(_module, _module, init.c_str(), init.size());
+ ostringstream str;
+ str << "__js" << i;
+ _module = str.str();
+ nasalsys->createModule(_module.c_str(), _module.c_str(), "", 0);
vector<SGPropertyNode_ptr> nasal = js_node->getChildren("nasal");
unsigned int j;
for (j = 0; j < nasal.size(); j++) {
- nasal[j]->setStringValue("module", _module);
+ nasal[j]->setStringValue("module", _module.c_str());
nasalsys->handleCommand(nasal[j]);
}
FGInput::_init_mouse ()
{
SG_LOG(SG_INPUT, SG_DEBUG, "Initializing mouse bindings");
- _module[0] = 0;
+ _module = "";
SGPropertyNode * mouse_nodes = fgGetNode("/input/mice");
if (mouse_nodes == 0) {
const char *cmd = bindings[i]->getStringValue("command");
SG_LOG(SG_INPUT, SG_DEBUG, "Reading binding " << cmd);
- if (!strcmp(cmd, "nasal") && _module[0])
- bindings[i]->setStringValue("module", _module);
+ if (!strcmp(cmd, "nasal") && !_module.empty())
+ bindings[i]->setStringValue("module", _module.c_str());
binding_list[modifiers].push_back(new SGBinding(bindings[i], globals->get_props()));
}
if (node->getChild("mod-alt") != 0)
_read_bindings(node->getChild("mod-alt"), binding_list,
modifiers|KEYMOD_ALT);
+
+ if (node->getChild("mod-meta") != 0)
+ _read_bindings(node->getChild("mod-meta"), binding_list,
+ modifiers|KEYMOD_META);
+
+ if (node->getChild("mod-super") != 0)
+ _read_bindings(node->getChild("mod-super"), binding_list,
+ modifiers|KEYMOD_SUPER);
+
+ if (node->getChild("mod-hyper") != 0)
+ _read_bindings(node->getChild("mod-hyper"), binding_list,
+ modifiers|KEYMOD_HYPER);
}
FGInput::mouse::mouse ()
: x(-1),
y(-1),
+ save_x(-1),
+ save_y(-1),
nModes(1),
current_mode(0),
modes(0)