diff options
author | Luo Jinghua <sunmoon1997@gmail.com> | 2010-10-21 18:47:10 +0800 |
---|---|---|
committer | Luo Jinghua <sunmoon1997@gmail.com> | 2010-10-22 11:26:26 +0800 |
commit | f5f6b4ecdb93ec47fa254bdeb9beedfa5d9b6ef6 (patch) | |
tree | adc35d1b1eea6c439871b7035bcdde8d5eeed17b | |
parent | 90992fbf8aeb4699d3eb99ee6fe590ad99291299 (diff) |
linux: support keyboard without X
-rw-r--r-- | includes/linux/EventHelpers.h | 1 | ||||
-rw-r--r-- | includes/linux/LinuxKeyboardEvents.h | 123 | ||||
-rwxr-xr-x | src/Makefile.am | 1 | ||||
-rw-r--r-- | src/linux/EventHelpers.cpp | 46 | ||||
-rwxr-xr-x | src/linux/LinuxInputManager.cpp | 42 | ||||
-rw-r--r-- | src/linux/LinuxKeyboardEvents.cpp | 432 |
6 files changed, 636 insertions, 9 deletions
diff --git a/includes/linux/EventHelpers.h b/includes/linux/EventHelpers.h index f149e7f..9c15423 100644 --- a/includes/linux/EventHelpers.h +++ b/includes/linux/EventHelpers.h @@ -36,6 +36,7 @@ namespace OIS static bool isJoyStick( int deviceID, JoyStickInfo &js ); static bool isMouse( int deviceID, JoyStickInfo &js ); static bool isMouse( int ) {return false;} + static bool isKeyboard( int deviceID, JoyStickInfo &js ); static bool isKeyboard( int ) {return false;} //Double pointer is so that we can set the value of the sent pointer diff --git a/includes/linux/LinuxKeyboardEvents.h b/includes/linux/LinuxKeyboardEvents.h new file mode 100644 index 0000000..c95f799 --- /dev/null +++ b/includes/linux/LinuxKeyboardEvents.h @@ -0,0 +1,123 @@ +/* +The zlib/libpng License + +Copyright (c) 2005-2007 Phillip Castaneda (pjcast -- www.wreckedgames.com) + +This software is provided 'as-is', without any express or implied warranty. In no event will +the authors be held liable for any damages arising from the use of this software. + +Permission is granted to anyone to use this software for any purpose, including commercial +applications, and to alter it and redistribute it freely, subject to the following +restrictions: + + 1. The origin of this software must not be misrepresented; you must not claim that + you wrote the original software. If you use this software in a product, + an acknowledgment in the product documentation would be appreciated but is + not required. + + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + + 3. This notice may not be removed or altered from any source distribution. +*/ +#ifndef _LINUX_KEYBOARD_EVENTS_HEADER_ +#define _LINUX_KEYBOARD_EVENTS_HEADER_ + +#include "linux/LinuxPrereqs.h" +#include "OISKeyboard.h" + +namespace OIS +{ + /** + Linux specialization of Keyboard class.. This version is favored over the other.. and has the + *possibility* of Force Feedback.. notice I say possibility, i make no gaurantees under linux, + as FF support is sketchy at best AFAIK. + */ + class LinuxKeyboardEvents : public Keyboard + { + public: + LinuxKeyboardEvents(InputManager* creator, bool buffered, const KeyboardInfo& js); + virtual ~LinuxKeyboardEvents(); + + /** @copydoc Keyboard::isKeyDown */ + virtual bool isKeyDown( KeyCode key ); + + /** @copydoc Keyboard::getAsString */ + virtual const std::string& getAsString( KeyCode kc ); + + /** @copydoc Keyboard::copyKeyStates */ + virtual void copyKeyStates( char keys[256] ); + + /** @copydoc Object::setBuffered */ + virtual void setBuffered(bool buffered); + + /** @copydoc Object::capture */ + virtual void capture(); + + /** @copydoc Object::queryInterface */ + virtual Interface* queryInterface(Interface::IType type); + + /** @copydoc Object::_initialize */ + virtual void _initialize(); + + /** + @remarks + For internal use only... Returns a structure to the manager, to make the device + availiable for use again + */ + KeyboardInfo _getKeyboardInfo(); + + static KeyboardInfoList _scanKeyboards(); + static void _clearKeyboards(KeyboardInfoList &joys); + protected: + bool _injectKeyDown( int key, int text ); + bool _injectKeyUp( int key ); + + int mKeyboard; + //! 1:1 Conversion Map between Linux Events and OIS KeyCodes + typedef std::map<int, KeyCode> Evt2OIS_KeyMap; + Evt2OIS_KeyMap keyConversion; + + struct ShiftTable { + int chars[2]; + + ShiftTable(const ShiftTable &other) + { + chars[0] = other.chars[0]; + chars[1] = other.chars[1]; + } + + ShiftTable() + { + chars[0] = 0; + chars[1] = 0; + } + + ShiftTable(int a) + { + chars[0] = a; + chars[1] = a; + } + + ShiftTable(int a, int b) + { + chars[0] = a; + chars[1] = b; + } + + int operator [] (int i) const + { + return chars[i]; + } + }; + typedef std::map<KeyCode, ShiftTable> OIS2TXT_KeyMap; + OIS2TXT_KeyMap txtConversion; + + //! Depressed Key List + char KeyBuffer[256]; + int mCapsLock; + + std::string mGetString; + }; +} +#endif //_LINUX_KEYBOARD_EVENTS_H_EADER_ diff --git a/src/Makefile.am b/src/Makefile.am index 7d63ffa..7ddaa71 100755 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -15,6 +15,7 @@ libOIS_la_SOURCES = OISInputManager.cpp \ ./linux/LinuxJoyStickEvents.cpp \ ./linux/LinuxMouseEvents.cpp \ ./linux/LinuxForceFeedback.cpp \ + ./linux/LinuxKeyboardEvents.cpp \ ./linux/LinuxKeyboard.cpp \ ./linux/LinuxMouse.cpp diff --git a/src/linux/EventHelpers.cpp b/src/linux/EventHelpers.cpp index 772e2a5..aac32e2 100644 --- a/src/linux/EventHelpers.cpp +++ b/src/linux/EventHelpers.cpp @@ -191,7 +191,7 @@ bool EventUtils::isMouse( int deviceID, MouseInfo &mouse ) } //Mouse Buttons found, so it must be a mousestick or pad - if( mouseButtonFound && info.relAxes.size() ) + if( info.relAxes.size() || info.absAxes.size() ) { mouse.joyFileD = deviceID; mouse.vendor = getName(deviceID); @@ -218,9 +218,51 @@ bool EventUtils::isMouse( int deviceID, MouseInfo &mouse ) ++axes; } + + return true; + } + + return false; +} + +//-----------------------------------------------------------------------------// +bool EventUtils::isKeyboard( int deviceID, KeyboardInfo &keyboard ) +{ + if( deviceID == -1 ) OIS_EXCEPT( E_General, "Error with File Descriptor" ); + + DeviceComponentInfo info = getComponentInfo( deviceID ); + + int buttons = 0; + bool keyboardButtonFound = false; + keyboard.button_map.clear(); + + #ifdef OIS_LINUX_KEYBOARD_DEBUG + cout << "\n\nDisplaying ButtonMapping Status:"; + #endif + for(std::vector<int>::iterator i = info.buttons.begin(), e = info.buttons.end(); i != e; ++i ) + { + //Check to ensure we find at least one keyboard only button + if( (*i >= KEY_RESERVED && *i <= KEY_UNKNOWN) ) + keyboardButtonFound = true; + + keyboard.button_map[*i] = buttons++; + + #ifdef OIS_LINUX_KEYBOARD_DEBUG + cout << "\nButton Mapping ID (hex): " << hex << *i << " OIS Button Num: " << dec << (buttons-1); + #endif + } + + //Keyboard Buttons found, so it must be a keyboardstick or pad + if( keyboardButtonFound ) + { + keyboard.joyFileD = deviceID; + keyboard.vendor = getName(deviceID); + keyboard.buttons = buttons; + keyboard.axes = 0; + keyboard.hats = 0; } - return mouseButtonFound; + return keyboardButtonFound; } //-----------------------------------------------------------------------------// diff --git a/src/linux/LinuxInputManager.cpp b/src/linux/LinuxInputManager.cpp index f4faf4c..bf891ea 100755 --- a/src/linux/LinuxInputManager.cpp +++ b/src/linux/LinuxInputManager.cpp @@ -21,6 +21,7 @@ restrictions: 3. This notice may not be removed or altered from any source distribution. */ #include "linux/LinuxInputManager.h" +#include "linux/LinuxKeyboardEvents.h" #include "linux/LinuxKeyboard.h" #include "linux/LinuxJoyStickEvents.h" #include "linux/LinuxMouseEvents.h" @@ -53,6 +54,9 @@ LinuxInputManager::~LinuxInputManager() //Close all mouses LinuxMouseEvents::_clearMouses(unusedMouseList); + //Close all mouses + LinuxKeyboardEvents::_clearKeyboards(unusedKeyboardList); + //Close all joysticks LinuxJoyStick::_clearJoys(unusedJoyStickList); } @@ -108,6 +112,10 @@ void LinuxInputManager::_enumerateDevices() unusedMouseList = LinuxMouseEvents::_scanMouses(); mouses = unusedMouseList.size(); + //Enumerate all attached keyboard devices + unusedKeyboardList = LinuxKeyboardEvents::_scanKeyboards(); + keyboards = unusedKeyboardList.size(); + //Enumerate all attached joystick devices unusedJoyStickList = LinuxJoyStick::_scanJoys(); joySticks = unusedJoyStickList.size(); @@ -130,6 +138,9 @@ DeviceList LinuxInputManager::freeDeviceList() for(MouseInfoList::iterator i = unusedMouseList.begin(); i != unusedMouseList.end(); ++i) ret.insert(std::make_pair(OISMouse, i->vendor)); + for(KeyboardInfoList::iterator i = unusedKeyboardList.begin(); i != unusedKeyboardList.end(); ++i) + ret.insert(std::make_pair(OISKeyboard, i->vendor)); + return ret; } @@ -138,7 +149,7 @@ int LinuxInputManager::totalDevices(Type iType) { switch(iType) { - case OISKeyboard: return 1; + case OISKeyboard: return 1 + keyboards; case OISMouse: return 1 + mouses; case OISJoyStick: return joySticks; default: return 0; @@ -150,7 +161,7 @@ int LinuxInputManager::freeDevices(Type iType) { switch(iType) { - case OISKeyboard: return keyboardUsed ? 0 : 1; + case OISKeyboard: return keyboardUsed ? 0 : 1 + (int)unusedKeyboardList.size(); case OISMouse: return (mouseUsed ? 0 : 1) + (int)unusedMouseList.size(); case OISJoyStick: return (int)unusedJoyStickList.size(); default: return 0; @@ -184,21 +195,34 @@ bool LinuxInputManager::vendorExist(Type iType, const std::string & vendor) Object* LinuxInputManager::createObject(InputManager *creator, Type iType, bool bufferMode, const std::string & vendor) { Object *obj = 0; + bool haveX11 = false; + +#ifdef HAVE_X11 + haveX11 = true; +#endif switch(iType) { case OISKeyboard: { - if( keyboardUsed == false ) + if( (haveX11 || unusedKeyboardList.empty()) && keyboardUsed == false ) obj = new LinuxKeyboard(this, bufferMode, grabKeyboard, useXRepeat); + if (!obj) + { + for(KeyboardInfoList::iterator i = unusedKeyboardList.begin(); i != unusedKeyboardList.end(); ++i) + { + if(vendor == "" || i->vendor == vendor) + { + obj = new LinuxKeyboardEvents(this, bufferMode, *i); + unusedKeyboardList.erase(i); + break; + } + } + } break; } case OISMouse: { - bool haveX11 = false; -#ifdef HAVE_X11 - haveX11 = true; -#endif if( (haveX11 || unusedMouseList.empty()) && mouseUsed == false ) { @@ -254,6 +278,10 @@ void LinuxInputManager::destroyObject( Object* obj ) { unusedMouseList.push_back( ((LinuxMouseEvents*)obj)->_getMouseInfo() ); } + if( obj->type() == OISMouse && obj->vendor() != mInputSystemName ) + { + unusedKeyboardList.push_back( ((LinuxKeyboardEvents*)obj)->_getKeyboardInfo() ); + } delete obj; } diff --git a/src/linux/LinuxKeyboardEvents.cpp b/src/linux/LinuxKeyboardEvents.cpp new file mode 100644 index 0000000..9c0d743 --- /dev/null +++ b/src/linux/LinuxKeyboardEvents.cpp @@ -0,0 +1,432 @@ +/* +The zlib/libpng License + +Copyright (c) 2005-2007 Phillip Castaneda (pjcast -- www.wreckedgames.com) + +This software is provided 'as-is', without any express or implied warranty. In no event will +the authors be held liable for any damages arising from the use of this software. + +Permission is granted to anyone to use this software for any purpose, including commercial +applications, and to alter it and redistribute it freely, subject to the following +restrictions: + + 1. The origin of this software must not be misrepresented; you must not claim that + you wrote the original software. If you use this software in a product, + an acknowledgment in the product documentation would be appreciated but is + not required. + + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "OISConfig.h" + +#include "linux/LinuxKeyboardEvents.h" +#include "linux/LinuxInputManager.h" +#include "linux/LinuxForceFeedback.h" +#include "linux/EventHelpers.h" + +#include "OISEvents.h" +#include "OISException.h" + +#include <fcntl.h> //Needed to Open a file descriptor +#include <cassert> +#include <string.h> +#include <linux/input.h> + +#include <sstream> + +using namespace OIS; + +//#define OIS_LINUX_KEYBOARD_DEBUG + +#ifdef OIS_LINUX_KEYBOARD_DEBUG +# include <iostream> + using namespace std; +#endif + +//-------------------------------------------------------------------// +LinuxKeyboardEvents::LinuxKeyboardEvents(InputManager* creator, bool buffered, const KeyboardInfo& keyboard) + : Keyboard(keyboard.vendor, buffered, keyboard.devId, creator) +{ + mKeyboard = keyboard.joyFileD; + mCapsLock = 0; + + txtConversion.insert(OIS2TXT_KeyMap::value_type(KC_1, ShiftTable('1', '!'))); + txtConversion.insert(OIS2TXT_KeyMap::value_type(KC_2, ShiftTable('2', '@'))); + txtConversion.insert(OIS2TXT_KeyMap::value_type(KC_3, ShiftTable('3', '#'))); + txtConversion.insert(OIS2TXT_KeyMap::value_type(KC_4, ShiftTable('4', '$'))); + txtConversion.insert(OIS2TXT_KeyMap::value_type(KC_5, ShiftTable('5', '%'))); + txtConversion.insert(OIS2TXT_KeyMap::value_type(KC_6, ShiftTable('6', '^'))); + txtConversion.insert(OIS2TXT_KeyMap::value_type(KC_7, ShiftTable('7', '&'))); + txtConversion.insert(OIS2TXT_KeyMap::value_type(KC_8, ShiftTable('8', '*'))); + txtConversion.insert(OIS2TXT_KeyMap::value_type(KC_9, ShiftTable('9', '('))); + txtConversion.insert(OIS2TXT_KeyMap::value_type(KC_0, ShiftTable('0', ')'))); + + txtConversion.insert(OIS2TXT_KeyMap::value_type(KC_A, ShiftTable('a', 'A'))); + txtConversion.insert(OIS2TXT_KeyMap::value_type(KC_B, ShiftTable('b', 'B'))); + txtConversion.insert(OIS2TXT_KeyMap::value_type(KC_C, ShiftTable('c', 'C'))); + txtConversion.insert(OIS2TXT_KeyMap::value_type(KC_D, ShiftTable('d', 'D'))); + txtConversion.insert(OIS2TXT_KeyMap::value_type(KC_E, ShiftTable('e', 'E'))); + txtConversion.insert(OIS2TXT_KeyMap::value_type(KC_F, ShiftTable('f', 'F'))); + txtConversion.insert(OIS2TXT_KeyMap::value_type(KC_G, ShiftTable('g', 'G'))); + txtConversion.insert(OIS2TXT_KeyMap::value_type(KC_H, ShiftTable('h', 'H'))); + txtConversion.insert(OIS2TXT_KeyMap::value_type(KC_I, ShiftTable('i', 'I'))); + txtConversion.insert(OIS2TXT_KeyMap::value_type(KC_J, ShiftTable('j', 'J'))); + txtConversion.insert(OIS2TXT_KeyMap::value_type(KC_K, ShiftTable('k', 'K'))); + txtConversion.insert(OIS2TXT_KeyMap::value_type(KC_L, ShiftTable('l', 'L'))); + txtConversion.insert(OIS2TXT_KeyMap::value_type(KC_M, ShiftTable('m', 'M'))); + txtConversion.insert(OIS2TXT_KeyMap::value_type(KC_N, ShiftTable('n', 'N'))); + txtConversion.insert(OIS2TXT_KeyMap::value_type(KC_O, ShiftTable('o', 'O'))); + txtConversion.insert(OIS2TXT_KeyMap::value_type(KC_P, ShiftTable('p', 'P'))); + txtConversion.insert(OIS2TXT_KeyMap::value_type(KC_Q, ShiftTable('q', 'Q'))); + txtConversion.insert(OIS2TXT_KeyMap::value_type(KC_R, ShiftTable('r', 'R'))); + txtConversion.insert(OIS2TXT_KeyMap::value_type(KC_S, ShiftTable('s', 'S'))); + txtConversion.insert(OIS2TXT_KeyMap::value_type(KC_T, ShiftTable('t', 'T'))); + txtConversion.insert(OIS2TXT_KeyMap::value_type(KC_U, ShiftTable('u', 'U'))); + txtConversion.insert(OIS2TXT_KeyMap::value_type(KC_V, ShiftTable('v', 'V'))); + txtConversion.insert(OIS2TXT_KeyMap::value_type(KC_W, ShiftTable('w', 'W'))); + txtConversion.insert(OIS2TXT_KeyMap::value_type(KC_X, ShiftTable('x', 'X'))); + txtConversion.insert(OIS2TXT_KeyMap::value_type(KC_Y, ShiftTable('y', 'Y'))); + txtConversion.insert(OIS2TXT_KeyMap::value_type(KC_Z, ShiftTable('z', 'Z'))); + + txtConversion.insert(OIS2TXT_KeyMap::value_type(KC_RETURN, ShiftTable('\n'))); + txtConversion.insert(OIS2TXT_KeyMap::value_type(KC_SPACE, ShiftTable(' '))); + txtConversion.insert(OIS2TXT_KeyMap::value_type(KC_TAB, ShiftTable('\t'))); + txtConversion.insert(OIS2TXT_KeyMap::value_type(KC_GRAVE, ShiftTable('`', '~'))); + txtConversion.insert(OIS2TXT_KeyMap::value_type(KC_MINUS, ShiftTable('-', '_'))); + txtConversion.insert(OIS2TXT_KeyMap::value_type(KC_EQUALS, ShiftTable('=', '+'))); + txtConversion.insert(OIS2TXT_KeyMap::value_type(KC_SLASH, ShiftTable('/', '?'))); + txtConversion.insert(OIS2TXT_KeyMap::value_type(KC_BACKSLASH, ShiftTable('\\', '|'))); + txtConversion.insert(OIS2TXT_KeyMap::value_type(KC_LBRACKET, ShiftTable('[', '{'))); + txtConversion.insert(OIS2TXT_KeyMap::value_type(KC_RBRACKET, ShiftTable(']', '}'))); + txtConversion.insert(OIS2TXT_KeyMap::value_type(KC_COMMA, ShiftTable(',', '<'))); + txtConversion.insert(OIS2TXT_KeyMap::value_type(KC_PERIOD, ShiftTable(',', '>'))); + + keyConversion.insert(Evt2OIS_KeyMap::value_type(KEY_1, KC_1)); + keyConversion.insert(Evt2OIS_KeyMap::value_type(KEY_2, KC_2)); + keyConversion.insert(Evt2OIS_KeyMap::value_type(KEY_3, KC_3)); + keyConversion.insert(Evt2OIS_KeyMap::value_type(KEY_4, KC_4)); + keyConversion.insert(Evt2OIS_KeyMap::value_type(KEY_5, KC_5)); + keyConversion.insert(Evt2OIS_KeyMap::value_type(KEY_6, KC_6)); + keyConversion.insert(Evt2OIS_KeyMap::value_type(KEY_7, KC_7)); + keyConversion.insert(Evt2OIS_KeyMap::value_type(KEY_8, KC_8)); + keyConversion.insert(Evt2OIS_KeyMap::value_type(KEY_9, KC_9)); + keyConversion.insert(Evt2OIS_KeyMap::value_type(KEY_0, KC_0)); + + keyConversion.insert(Evt2OIS_KeyMap::value_type(KEY_B, KC_B)); + keyConversion.insert(Evt2OIS_KeyMap::value_type(KEY_A, KC_A)); + keyConversion.insert(Evt2OIS_KeyMap::value_type(KEY_C, KC_C)); + keyConversion.insert(Evt2OIS_KeyMap::value_type(KEY_D, KC_D)); + keyConversion.insert(Evt2OIS_KeyMap::value_type(KEY_E, KC_E)); + keyConversion.insert(Evt2OIS_KeyMap::value_type(KEY_F, KC_F)); + keyConversion.insert(Evt2OIS_KeyMap::value_type(KEY_G, KC_G)); + keyConversion.insert(Evt2OIS_KeyMap::value_type(KEY_H, KC_H)); + keyConversion.insert(Evt2OIS_KeyMap::value_type(KEY_I, KC_I)); + keyConversion.insert(Evt2OIS_KeyMap::value_type(KEY_J, KC_J)); + keyConversion.insert(Evt2OIS_KeyMap::value_type(KEY_K, KC_K)); + keyConversion.insert(Evt2OIS_KeyMap::value_type(KEY_L, KC_L)); + keyConversion.insert(Evt2OIS_KeyMap::value_type(KEY_M, KC_M)); + keyConversion.insert(Evt2OIS_KeyMap::value_type(KEY_N, KC_N)); + keyConversion.insert(Evt2OIS_KeyMap::value_type(KEY_O, KC_O)); + keyConversion.insert(Evt2OIS_KeyMap::value_type(KEY_P, KC_P)); + keyConversion.insert(Evt2OIS_KeyMap::value_type(KEY_Q, KC_Q)); + keyConversion.insert(Evt2OIS_KeyMap::value_type(KEY_R, KC_R)); + keyConversion.insert(Evt2OIS_KeyMap::value_type(KEY_S, KC_S)); + keyConversion.insert(Evt2OIS_KeyMap::value_type(KEY_T, KC_T)); + keyConversion.insert(Evt2OIS_KeyMap::value_type(KEY_U, KC_U)); + keyConversion.insert(Evt2OIS_KeyMap::value_type(KEY_V, KC_V)); + keyConversion.insert(Evt2OIS_KeyMap::value_type(KEY_W, KC_W)); + keyConversion.insert(Evt2OIS_KeyMap::value_type(KEY_X, KC_X)); + keyConversion.insert(Evt2OIS_KeyMap::value_type(KEY_Y, KC_Y)); + keyConversion.insert(Evt2OIS_KeyMap::value_type(KEY_Z, KC_Z)); + + keyConversion.insert(Evt2OIS_KeyMap::value_type(KEY_F1, KC_F1)); + keyConversion.insert(Evt2OIS_KeyMap::value_type(KEY_F2, KC_F2)); + keyConversion.insert(Evt2OIS_KeyMap::value_type(KEY_F3, KC_F3)); + keyConversion.insert(Evt2OIS_KeyMap::value_type(KEY_F4, KC_F4)); + keyConversion.insert(Evt2OIS_KeyMap::value_type(KEY_F5, KC_F5)); + keyConversion.insert(Evt2OIS_KeyMap::value_type(KEY_F6, KC_F6)); + keyConversion.insert(Evt2OIS_KeyMap::value_type(KEY_F7, KC_F7)); + keyConversion.insert(Evt2OIS_KeyMap::value_type(KEY_F8, KC_F8)); + keyConversion.insert(Evt2OIS_KeyMap::value_type(KEY_F9, KC_F9)); + keyConversion.insert(Evt2OIS_KeyMap::value_type(KEY_F10, KC_F10)); + keyConversion.insert(Evt2OIS_KeyMap::value_type(KEY_F11, KC_F11)); + keyConversion.insert(Evt2OIS_KeyMap::value_type(KEY_F12, KC_F12)); + keyConversion.insert(Evt2OIS_KeyMap::value_type(KEY_F13, KC_F13)); + keyConversion.insert(Evt2OIS_KeyMap::value_type(KEY_F14, KC_F14)); + keyConversion.insert(Evt2OIS_KeyMap::value_type(KEY_F15, KC_F15)); + + keyConversion.insert(Evt2OIS_KeyMap::value_type(KEY_UP, KC_UP)); + keyConversion.insert(Evt2OIS_KeyMap::value_type(KEY_DOWN, KC_DOWN)); + keyConversion.insert(Evt2OIS_KeyMap::value_type(KEY_LEFT, KC_LEFT)); + keyConversion.insert(Evt2OIS_KeyMap::value_type(KEY_RIGHT, KC_RIGHT)); + + keyConversion.insert(Evt2OIS_KeyMap::value_type(KEY_PAGEUP, KC_PGUP)); + keyConversion.insert(Evt2OIS_KeyMap::value_type(KEY_PAGEDOWN, KC_PGDOWN)); + keyConversion.insert(Evt2OIS_KeyMap::value_type(KEY_HOME, KC_HOME)); + keyConversion.insert(Evt2OIS_KeyMap::value_type(KEY_END, KC_END)); + + keyConversion.insert(Evt2OIS_KeyMap::value_type(KEY_RIGHTCTRL, KC_RCONTROL)); + keyConversion.insert(Evt2OIS_KeyMap::value_type(KEY_LEFTCTRL, KC_LCONTROL)); + keyConversion.insert(Evt2OIS_KeyMap::value_type(KEY_RIGHTSHIFT, KC_RSHIFT)); + keyConversion.insert(Evt2OIS_KeyMap::value_type(KEY_LEFTSHIFT, KC_LSHIFT)); + keyConversion.insert(Evt2OIS_KeyMap::value_type(KEY_RIGHTALT, KC_RMENU)); + keyConversion.insert(Evt2OIS_KeyMap::value_type(KEY_LEFTALT, KC_LMENU)); + + keyConversion.insert(Evt2OIS_KeyMap::value_type(KEY_INSERT, KC_INSERT)); + keyConversion.insert(Evt2OIS_KeyMap::value_type(KEY_DELETE, KC_DELETE)); + + keyConversion.insert(Evt2OIS_KeyMap::value_type(KEY_ESC, KC_ESCAPE)); + keyConversion.insert(Evt2OIS_KeyMap::value_type(KEY_CAPSLOCK, KC_CAPITAL)); + + keyConversion.insert(Evt2OIS_KeyMap::value_type(KEY_TAB, KC_TAB)); + keyConversion.insert(Evt2OIS_KeyMap::value_type(KEY_ENTER, KC_RETURN)); + keyConversion.insert(Evt2OIS_KeyMap::value_type(KEY_BACK, KC_BACK)); + keyConversion.insert(Evt2OIS_KeyMap::value_type(KEY_SPACE, KC_SPACE)); + keyConversion.insert(Evt2OIS_KeyMap::value_type(KEY_GRAVE, KC_GRAVE)); + keyConversion.insert(Evt2OIS_KeyMap::value_type(KEY_MINUS, KC_MINUS)); + keyConversion.insert(Evt2OIS_KeyMap::value_type(KEY_EQUAL, KC_EQUALS)); + keyConversion.insert(Evt2OIS_KeyMap::value_type(KEY_SLASH, KC_SLASH)); + keyConversion.insert(Evt2OIS_KeyMap::value_type(KEY_BACKSLASH, KC_BACKSLASH)); + keyConversion.insert(Evt2OIS_KeyMap::value_type(KEY_LEFTBRACE, KC_LBRACKET)); + keyConversion.insert(Evt2OIS_KeyMap::value_type(KEY_RIGHTBRACE, KC_RBRACKET)); + keyConversion.insert(Evt2OIS_KeyMap::value_type(KEY_COMMA, KC_COMMA)); + keyConversion.insert(Evt2OIS_KeyMap::value_type(KEY_DOT, KC_PERIOD)); +} + +//-------------------------------------------------------------------// +LinuxKeyboardEvents::~LinuxKeyboardEvents() +{ +} + +//-------------------------------------------------------------------// +void LinuxKeyboardEvents::_initialize() +{ + //Clear our keyboard state buffer + memset( &KeyBuffer, 0, 256 ); + mModifiers = 0; + + if( mKeyboard == -1 ) + OIS_EXCEPT(E_InputDeviceNonExistant, + "LinuxKeyboard::_initialize() >> Keyboard Not Found!"); +} + +//-------------------------------------------------------------------// +bool LinuxKeyboardEvents::isKeyDown( KeyCode key ) +{ + return (KeyBuffer[key]); +} + +//-------------------------------------------------------------------// +void LinuxKeyboardEvents::capture() +{ +#define KEYBOARD_BUFFERSIZE 64 + //We are in non blocking mode - we just read once, and try to fill up buffer + input_event keyboard[KEYBOARD_BUFFERSIZE]; + int ret = read(mKeyboard, &keyboard, sizeof(struct input_event) * KEYBOARD_BUFFERSIZE); + if( ret <= 0 ) + return; + + //Determine how many whole events re read up + ret /= sizeof(struct input_event); + for(int i = 0; i < ret; ++i) + { + switch(keyboard[i].type) + { + case EV_KEY: //Button + { + KeyCode button; + int text = 0; + + #ifdef OIS_LINUX_KEYBOARD_DEBUG + std::cout << "keycode: " << keyboard[i].code << " value " \ + << keyboard[i].value << std::endl; + #endif + + int code = keyboard[i].code; + if (keyConversion.find(code) == keyConversion.end()) + continue; + + button = keyConversion[code]; + if (txtConversion.find(button) != txtConversion.end() && + mTextMode != Off) + text = txtConversion[button][mCapsLock ^ (!!(mModifiers & Shift))]; + + #ifdef OIS_LINUX_KEYBOARD_DEBUG + std::cout << "\nButton Code: " << keyboard[i].code << ", OIS Value: " << button << std::endl; + #endif + + //Check to see whether push or released event... + if (keyboard[i].value) + _injectKeyDown(code, text); + else + _injectKeyUp(code); + break; + } + default: + break; + } + } +} + +//-------------------------------------------------------------------// +void LinuxKeyboardEvents::setBuffered(bool buffered) +{ + if( buffered != mBuffered ) + { + mBuffered = buffered; + _initialize(); + } +} + +//-------------------------------------------------------------------// +KeyboardInfo LinuxKeyboardEvents::_getKeyboardInfo() +{ + KeyboardInfo keyboard; + + keyboard.devId = mDevID; + keyboard.joyFileD = mKeyboard; + keyboard.vendor = mVendor; + + return keyboard; +} + +//-------------------------------------------------------------------// +KeyboardInfoList LinuxKeyboardEvents::_scanKeyboards() +{ + KeyboardInfoList keyboards; + + //Search through all of the event devices.. and identify which ones are keyboards + //xxx move this to InputManager, as it can also scan all other events + for(int i = 0; i < 255; ++i ) + { + std::stringstream s; + s << "/dev/input/event" << i; + int fd = open( s.str().c_str(), O_RDONLY |O_NONBLOCK ); + if (fd == -1) + continue; + + #ifdef OIS_LINUX_KEYBOARD_DEBUG + std::cout << "\nOpening " << s.str() << "..."; + #endif + try + { + KeyboardInfo keyboard; + if( EventUtils::isKeyboard(fd, keyboard) ) + { + keyboards.push_back(keyboard); + #ifdef OIS_LINUX_KEYBOARD_DEBUG + std::cout << "\n__Keyboard added to list"; + #endif + } + else + { + #ifdef OIS_LINUX_KEYBOARD_DEBUG + std::cout << "\n__Not a keyboard!!"; + #endif + close(fd); + } + } + catch(...) + { + #ifdef OIS_LINUX_KEYBOARD_DEBUG + std::cout << "\nException caught!!"; + #endif + close(fd); + } + } + +#ifdef OIS_LINUX_KEYBOARD_DEBUG + std::cout << "\n"; +#endif + + return keyboards; +} + +//-------------------------------------------------------------------// +bool LinuxKeyboardEvents::_injectKeyDown( int key, int text ) +{ + KeyCode kc = keyConversion[key]; + KeyBuffer[kc] = 1; + + //Turn on modifier flags + if( kc == KC_LCONTROL || kc == KC_RCONTROL) + mModifiers |= Ctrl; + else if( kc == KC_LSHIFT || kc == KC_RSHIFT ) + mModifiers |= Shift; + else if( kc == KC_LMENU || kc == KC_RMENU ) + mModifiers |= Alt; + + if( mBuffered && mListener ) + return mListener->keyPressed(KeyEvent(this, kc, text)); + + return true; +} + +//-------------------------------------------------------------------// +bool LinuxKeyboardEvents::_injectKeyUp( int key ) +{ + KeyCode kc = keyConversion[key]; + KeyBuffer[kc] = 0; + + //Turn off modifier flags + if( kc == KC_LCONTROL || kc == KC_RCONTROL) + mModifiers &= ~Ctrl; + else if( kc == KC_LSHIFT || kc == KC_RSHIFT ) + mModifiers &= ~Shift; + else if( kc == KC_LMENU || kc == KC_RMENU ) + mModifiers &= ~Alt; + + if ( kc == KC_CAPITAL) + mCapsLock ^= 1; + + if( mBuffered && mListener ) + return mListener->keyReleased(KeyEvent(this, kc, 0)); + + return true; +} + +//-------------------------------------------------------------------// +const std::string& LinuxKeyboardEvents::getAsString( KeyCode kc ) +{ + mGetString = "Unknown"; + char *temp = 0; + + Evt2OIS_KeyMap::iterator i = keyConversion.begin(), + e = keyConversion.end(); + + for( ; i != e; ++i ) + { + if( i->second == kc ) + { + //temp = XKeysymToString(i->first); + if( temp ) + mGetString = temp; + break; + } + } + + return mGetString; +} + +//-------------------------------------------------------------------// +void LinuxKeyboardEvents::copyKeyStates( char keys[256] ) +{ + memcpy( keys, KeyBuffer, 256 ); +} + +//-------------------------------------------------------------------// +void LinuxKeyboardEvents::_clearKeyboards(KeyboardInfoList &keyboards) +{ + for(KeyboardInfoList::iterator i = keyboards.begin(); i != keyboards.end(); ++i) + close(i->joyFileD); + keyboards.clear(); +} + +//-------------------------------------------------------------------// +Interface* LinuxKeyboardEvents::queryInterface(Interface::IType type) +{ + return 0; +} |