summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLuo Jinghua <sunmoon1997@gmail.com>2010-10-21 14:45:58 +0800
committerLuo Jinghua <sunmoon1997@gmail.com>2010-10-22 08:55:20 +0800
commit6875e66e7a4b5fa74486d5318a387a3674073ac8 (patch)
treef4f99636e7b300ea304cd53712ce9d6dfd4bdfd3 /src
parent213444d3638b99164c3efcbe2ede8c92303503ea (diff)
linux: support the event interface
Only mouse is supported.
Diffstat (limited to 'src')
-rwxr-xr-xsrc/Makefile.am3
-rw-r--r--src/linux/EventHelpers.cpp59
-rwxr-xr-xsrc/linux/LinuxInputManager.cpp50
-rwxr-xr-xsrc/linux/LinuxKeyboard.cpp15
-rwxr-xr-xsrc/linux/LinuxMouse.cpp11
-rw-r--r--src/linux/LinuxMouseEvents.cpp251
6 files changed, 381 insertions, 8 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index 83892d2..7d63ffa 100755
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -13,6 +13,7 @@ libOIS_la_SOURCES = OISInputManager.cpp \
./linux/EventHelpers.cpp \
./linux/LinuxInputManager.cpp \
./linux/LinuxJoyStickEvents.cpp \
+ ./linux/LinuxMouseEvents.cpp \
./linux/LinuxForceFeedback.cpp \
./linux/LinuxKeyboard.cpp \
./linux/LinuxMouse.cpp
@@ -20,6 +21,6 @@ libOIS_la_SOURCES = OISInputManager.cpp \
libOIS_la_LDFLAGS = -release @PACKAGE_VERSION@
#libOIS_la_LDFLAGS = -version-info $(shell echo "@PACKAGE_VERSION@" | tr '.' ':')
-libOIS_la_LIBADD = $(STLPORT_LIBS) -L/usr/X11R6/lib -lX11
+libOIS_la_LIBADD = $(STLPORT_LIBS) $(X11_LIBS)
#eof "$Id: Makefile.am,v 1.15.2.1 2008/02/14 03:33:36 pjcast Exp $"
diff --git a/src/linux/EventHelpers.cpp b/src/linux/EventHelpers.cpp
index 002ea41..772e2a5 100644
--- a/src/linux/EventHelpers.cpp
+++ b/src/linux/EventHelpers.cpp
@@ -164,6 +164,65 @@ bool EventUtils::isJoyStick( int deviceID, JoyStickInfo &js )
return joyButtonFound;
}
+bool EventUtils::isMouse( int deviceID, MouseInfo &mouse )
+{
+ if( deviceID == -1 ) OIS_EXCEPT( E_General, "Error with File Descriptor" );
+
+ DeviceComponentInfo info = getComponentInfo( deviceID );
+
+ int buttons = 0;
+ bool mouseButtonFound = false;
+ mouse.button_map.clear();
+
+ #ifdef OIS_LINUX_MOUSE_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 mouse only button
+ if( (*i >= BTN_MOUSE && *i <= BTN_JOYSTICK) )
+ mouseButtonFound = true;
+
+ mouse.button_map[*i] = buttons++;
+
+ #ifdef OIS_LINUX_MOUSE_DEBUG
+ cout << "\nButton Mapping ID (hex): " << hex << *i << " OIS Button Num: " << dec << (buttons-1);
+ #endif
+ }
+
+ //Mouse Buttons found, so it must be a mousestick or pad
+ if( mouseButtonFound && info.relAxes.size() )
+ {
+ mouse.joyFileD = deviceID;
+ mouse.vendor = getName(deviceID);
+ mouse.buttons = buttons;
+ mouse.axes = info.relAxes.size() + info.absAxes.size();
+ mouse.hats = info.hats.size();
+
+ //Map the Axes
+ #ifdef OIS_LINUX_MOUSE_DEBUG
+ cout << "\n\nDisplaying AxisMapping Status:";
+ #endif
+ int axes = 0;
+ for(std::vector<int>::iterator i = info.absAxes.begin(), e = info.absAxes.end(); i != e; ++i )
+ {
+ mouse.axis_map[*i] = axes;
+
+ input_absinfo absinfo;
+ ioctl(deviceID, EVIOCGABS(*i), &absinfo);
+ mouse.axis_range[axes] = Range(absinfo.minimum, absinfo.maximum);
+
+ #ifdef OIS_LINUX_MOUSE_DEBUG
+ cout << "\nAxis Mapping ID (hex): " << hex << *i << " OIS Axis Num: " << dec << axes;
+ #endif
+
+ ++axes;
+ }
+ }
+
+ return mouseButtonFound;
+}
+
//-----------------------------------------------------------------------------//
std::string EventUtils::getName( int deviceID )
{
diff --git a/src/linux/LinuxInputManager.cpp b/src/linux/LinuxInputManager.cpp
index 01fc23a..f4faf4c 100755
--- a/src/linux/LinuxInputManager.cpp
+++ b/src/linux/LinuxInputManager.cpp
@@ -23,6 +23,7 @@ restrictions:
#include "linux/LinuxInputManager.h"
#include "linux/LinuxKeyboard.h"
#include "linux/LinuxJoyStickEvents.h"
+#include "linux/LinuxMouseEvents.h"
#include "linux/LinuxMouse.h"
#include "OISException.h"
#include <cstdlib>
@@ -49,6 +50,9 @@ LinuxInputManager::LinuxInputManager() : InputManager("X11InputManager")
//--------------------------------------------------------------------------------//
LinuxInputManager::~LinuxInputManager()
{
+ //Close all mouses
+ LinuxMouseEvents::_clearMouses(unusedMouseList);
+
//Close all joysticks
LinuxJoyStick::_clearJoys(unusedJoyStickList);
}
@@ -65,6 +69,7 @@ void LinuxInputManager::_initialize( ParamList &paramList )
//--------------------------------------------------------------------------------//
void LinuxInputManager::_parseConfigSettings( ParamList &paramList )
{
+#ifdef HAVE_X11
ParamList::iterator i = paramList.find("WINDOW");
if( i == paramList.end() )
OIS_EXCEPT( E_InvalidParam, "LinuxInputManager >> No WINDOW!" );
@@ -93,12 +98,17 @@ void LinuxInputManager::_parseConfigSettings( ParamList &paramList )
if( i != paramList.end() )
if( i->second == "false" )
hideMouse = false;
+#endif
}
//--------------------------------------------------------------------------------//
void LinuxInputManager::_enumerateDevices()
{
- //Enumerate all attached devices
+ //Enumerate all attached mouse devices
+ unusedMouseList = LinuxMouseEvents::_scanMouses();
+ mouses = unusedMouseList.size();
+
+ //Enumerate all attached joystick devices
unusedJoyStickList = LinuxJoyStick::_scanJoys();
joySticks = unusedJoyStickList.size();
}
@@ -117,6 +127,9 @@ DeviceList LinuxInputManager::freeDeviceList()
for(JoyStickInfoList::iterator i = unusedJoyStickList.begin(); i != unusedJoyStickList.end(); ++i)
ret.insert(std::make_pair(OISJoyStick, i->vendor));
+ for(MouseInfoList::iterator i = unusedMouseList.begin(); i != unusedMouseList.end(); ++i)
+ ret.insert(std::make_pair(OISMouse, i->vendor));
+
return ret;
}
@@ -126,7 +139,7 @@ int LinuxInputManager::totalDevices(Type iType)
switch(iType)
{
case OISKeyboard: return 1;
- case OISMouse: return 1;
+ case OISMouse: return 1 + mouses;
case OISJoyStick: return joySticks;
default: return 0;
}
@@ -138,7 +151,7 @@ int LinuxInputManager::freeDevices(Type iType)
switch(iType)
{
case OISKeyboard: return keyboardUsed ? 0 : 1;
- case OISMouse: return mouseUsed ? 0 : 1;
+ case OISMouse: return (mouseUsed ? 0 : 1) + (int)unusedMouseList.size();
case OISJoyStick: return (int)unusedJoyStickList.size();
default: return 0;
}
@@ -151,6 +164,12 @@ bool LinuxInputManager::vendorExist(Type iType, const std::string & vendor)
{
return true;
}
+ else if( iType == OISMouse )
+ {
+ for(MouseInfoList::iterator i = unusedMouseList.begin(); i != unusedMouseList.end(); ++i)
+ if(i->vendor == vendor)
+ return true;
+ }
else if( iType == OISJoyStick )
{
for(JoyStickInfoList::iterator i = unusedJoyStickList.begin(); i != unusedJoyStickList.end(); ++i)
@@ -176,8 +195,27 @@ Object* LinuxInputManager::createObject(InputManager *creator, Type iType, bool
}
case OISMouse:
{
- if( mouseUsed == false )
+ bool haveX11 = false;
+#ifdef HAVE_X11
+ haveX11 = true;
+#endif
+
+ if( (haveX11 || unusedMouseList.empty()) && mouseUsed == false )
+ {
obj = new LinuxMouse(this, bufferMode, grabMouse, hideMouse);
+ }
+ if (!obj)
+ {
+ for(MouseInfoList::iterator i = unusedMouseList.begin(); i != unusedMouseList.end(); ++i)
+ {
+ if(vendor == "" || i->vendor == vendor)
+ {
+ obj = new LinuxMouseEvents(this, bufferMode, *i);
+ unusedMouseList.erase(i);
+ break;
+ }
+ }
+ }
break;
}
case OISJoyStick:
@@ -212,6 +250,10 @@ void LinuxInputManager::destroyObject( Object* obj )
{
unusedJoyStickList.push_back( ((LinuxJoyStick*)obj)->_getJoyInfo() );
}
+ if( obj->type() == OISMouse && obj->vendor() != mInputSystemName )
+ {
+ unusedMouseList.push_back( ((LinuxMouseEvents*)obj)->_getMouseInfo() );
+ }
delete obj;
}
diff --git a/src/linux/LinuxKeyboard.cpp b/src/linux/LinuxKeyboard.cpp
index 75d98ca..beafa3a 100755
--- a/src/linux/LinuxKeyboard.cpp
+++ b/src/linux/LinuxKeyboard.cpp
@@ -25,8 +25,11 @@ restrictions:
#include "OISException.h"
#include "OISEvents.h"
+#ifdef HAVE_X11
#include <X11/keysym.h>
#include <X11/Xutil.h>
+#endif
+
#include <cstring>
using namespace OIS;
@@ -35,6 +38,7 @@ using namespace OIS;
LinuxKeyboard::LinuxKeyboard(InputManager* creator, bool buffered, bool grab, bool useXRepeat)
: Keyboard(creator->inputSystemName(), buffered, 0, creator)
{
+#ifdef HAVE_X11
setlocale(LC_CTYPE, ""); //Set the locale to (hopefully) the users LANG UTF-8 Env var
display = 0;
@@ -185,7 +189,7 @@ LinuxKeyboard::LinuxKeyboard(InputManager* creator, bool buffered, bool grab, bo
keyConversion.insert(XtoOIS_KeyMap::value_type(XK_Super_L, KC_LWIN));
keyConversion.insert(XtoOIS_KeyMap::value_type(XK_Super_R, KC_RWIN));
keyConversion.insert(XtoOIS_KeyMap::value_type(XK_Menu, KC_APPS));
-
+#endif
static_cast<LinuxInputManager*>(mCreator)->_setKeyboardUsed(true);
}
@@ -196,6 +200,7 @@ void LinuxKeyboard::_initialize()
memset( &KeyBuffer, 0, 256 );
mModifiers = 0;
+#ifdef HAVE_X11
if( display ) XCloseDisplay(display);
display = 0;
window = static_cast<LinuxInputManager*>(mCreator)->_getWindow();
@@ -226,11 +231,13 @@ void LinuxKeyboard::_initialize()
XAutoRepeatOff( display );
}
+#endif
}
//-------------------------------------------------------------------//
LinuxKeyboard::~LinuxKeyboard()
{
+#ifdef HAVE_X11
if( display )
{
if( oldXAutoRepeat )
@@ -241,7 +248,7 @@ LinuxKeyboard::~LinuxKeyboard()
XCloseDisplay(display);
}
-
+#endif
static_cast<LinuxInputManager*>(mCreator)->_setKeyboardUsed(true);
}
@@ -297,6 +304,7 @@ bool LinuxKeyboard::isKeyDown( KeyCode key )
//-------------------------------------------------------------------//
void LinuxKeyboard::capture()
{
+#ifdef HAVE_X11
KeySym key;
XEvent event;
LinuxInputManager* linMan = static_cast<LinuxInputManager*>(mCreator);
@@ -371,6 +379,7 @@ void LinuxKeyboard::capture()
}
}
}
+#endif
}
//-------------------------------------------------------------------//
@@ -425,6 +434,7 @@ const std::string& LinuxKeyboard::getAsString( KeyCode kc )
mGetString = "Unknown";
char *temp = 0;
+#ifdef HAVE_X11
XtoOIS_KeyMap::iterator i = keyConversion.begin(),
e = keyConversion.end();
@@ -438,6 +448,7 @@ const std::string& LinuxKeyboard::getAsString( KeyCode kc )
break;
}
}
+#endif
return mGetString;
}
diff --git a/src/linux/LinuxMouse.cpp b/src/linux/LinuxMouse.cpp
index a12e030..c987447 100755
--- a/src/linux/LinuxMouse.cpp
+++ b/src/linux/LinuxMouse.cpp
@@ -53,6 +53,7 @@ void LinuxMouse::_initialize()
oldXMouseX = oldXMouseY = 6;
oldXMouseZ = 0;
+#ifdef HAVE_X11
if( display ) XCloseDisplay(display);
display = 0;
window = static_cast<LinuxInputManager*>(mCreator)->_getWindow();
@@ -78,6 +79,7 @@ void LinuxMouse::_initialize()
XAllocNamedColor( display, colormap, "black", &black, &dummy );
bm_no = XCreateBitmapFromData( display, window, no_data, 8, 8 );
cursor = XCreatePixmapCursor( display, bm_no, bm_no, &black, &black, 0, 0 );
+#endif
grab( grabMouse );
hide( hideMouse );
@@ -88,6 +90,7 @@ void LinuxMouse::_initialize()
//-------------------------------------------------------------------//
LinuxMouse::~LinuxMouse()
{
+#ifdef HAVE_X11
if( display )
{
grab(false);
@@ -95,7 +98,7 @@ LinuxMouse::~LinuxMouse()
XFreeCursor(display, cursor);
XCloseDisplay(display);
}
-
+#endif
static_cast<LinuxInputManager*>(mCreator)->_setMouseUsed(false);
}
@@ -152,6 +155,7 @@ void LinuxMouse::capture()
//-------------------------------------------------------------------//
void LinuxMouse::_processXEvents()
{
+#ifdef HAVE_X11
//X11 Button Events: 1=left 2=middle 3=right; Our Bit Postion: 1=Left 2=Right 3=Middle
char mask[4] = {0,1,4,2};
XEvent event;
@@ -249,22 +253,27 @@ void LinuxMouse::_processXEvents()
}
}
}
+#endif
}
//-------------------------------------------------------------------//
void LinuxMouse::grab(bool grab)
{
+#ifdef HAVE_X11
if( grab )
XGrabPointer(display, window, True, 0, GrabModeAsync, GrabModeAsync, window, None, CurrentTime);
else
XUngrabPointer(display, CurrentTime);
+#endif
}
//-------------------------------------------------------------------//
void LinuxMouse::hide(bool hide)
{
+#ifdef HAVE_X11
if( hide )
XDefineCursor(display, window, cursor);
else
XUndefineCursor(display, window);
+#endif
}
diff --git a/src/linux/LinuxMouseEvents.cpp b/src/linux/LinuxMouseEvents.cpp
new file mode 100644
index 0000000..bfe9ac6
--- /dev/null
+++ b/src/linux/LinuxMouseEvents.cpp
@@ -0,0 +1,251 @@
+/*
+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/LinuxMouseEvents.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 <linux/input.h>
+
+#include <sstream>
+
+using namespace OIS;
+
+//#define OIS_LINUX_MOUSE_DEBUG
+
+#ifdef OIS_LINUX_MOUSE_DEBUG
+# include <iostream>
+ using namespace std;
+#endif
+
+//-------------------------------------------------------------------//
+LinuxMouseEvents::LinuxMouseEvents(InputManager* creator, bool buffered, const MouseInfo& mouse)
+ : Mouse(mouse.vendor, buffered, mouse.devId, creator)
+{
+ mMouse = mouse.joyFileD;
+
+ mButtonMap = mouse.button_map;
+ mAxisMap = mouse.axis_map;
+ mRanges = mouse.axis_range;
+}
+
+//-------------------------------------------------------------------//
+LinuxMouseEvents::~LinuxMouseEvents()
+{
+}
+
+//-------------------------------------------------------------------//
+void LinuxMouseEvents::_initialize()
+{
+ mState.clear();
+
+ if( mMouse == -1 )
+ OIS_EXCEPT(E_InputDeviceNonExistant,
+ "LinuxMouse::_initialize() >> Mouse Not Found!");
+}
+
+//-------------------------------------------------------------------//
+void LinuxMouseEvents::capture()
+{
+ mState.X.rel = mState.Y.rel = mState.Z.rel = 0;
+
+ //Used to determine if an axis has been changed and needs an event
+ bool axisMoved = false;
+
+#define MOUSE_BUFFERSIZE 64
+ //We are in non blocking mode - we just read once, and try to fill up buffer
+ input_event mouse[MOUSE_BUFFERSIZE];
+ int ret = read(mMouse, &mouse, sizeof(struct input_event) * MOUSE_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(mouse[i].type)
+ {
+ case EV_KEY: //Button
+ {
+ MouseButtonID button = (MouseButtonID)mButtonMap[mouse[i].code];
+
+ #ifdef OIS_LINUX_MOUSE_DEBUG
+ std::cout << "\nButton Code: " << mouse[i].code << ", OIS Value: " << button << std::endl;
+ #endif
+
+ //Check to see whether push or released event...
+ if(mouse[i].value)
+ {
+ if( mBuffered && mListener )
+ if(!mListener->mousePressed(MouseEvent(this,mState), button)) return;
+ }
+ else
+ {
+ if( mBuffered && mListener )
+ if(!mListener->mouseReleased(MouseEvent(this,mState), button)) return;
+ }
+ break;
+ }
+ //Relative Axes (Do any mouses actually have a relative axis?)
+ case EV_REL:
+ switch (mouse[i].code)
+ {
+ case REL_X:
+ mState.X.rel = mouse[i].value;
+ axisMoved = true;
+ break;
+ case REL_Y:
+ mState.Y.rel = mouse[i].value;
+ axisMoved = true;
+ break;
+ case REL_Z:
+ mState.Z.rel = mouse[i].value;
+ axisMoved = true;
+ break;
+ default:
+ break;
+ }
+
+ default:
+ break;
+ }
+ }
+
+ if (axisMoved)
+ {
+ mState.X.abs += mState.X.rel;
+ mState.Y.abs += mState.Y.rel;
+ mState.Z.abs += mState.Z.rel;
+
+ //Clip values to window
+ if( mState.X.abs < 0 )
+ mState.X.abs = 0;
+ else if( mState.X.abs > mState.width )
+ mState.X.abs = mState.width;
+ if( mState.Y.abs < 0 )
+ mState.Y.abs = 0;
+ else if( mState.Y.abs > mState.height )
+ mState.Y.abs = mState.height;
+ }
+
+ //All axes and POVs are combined into one movement per pair per captured frame
+ if( mBuffered && mListener )
+ {
+ if( axisMoved && mListener->mouseMoved( MouseEvent(this,mState)) == false )
+ return;
+ }
+}
+
+//-------------------------------------------------------------------//
+void LinuxMouseEvents::setBuffered(bool buffered)
+{
+ if( buffered != mBuffered )
+ {
+ mBuffered = buffered;
+ _initialize();
+ }
+}
+
+//-------------------------------------------------------------------//
+MouseInfo LinuxMouseEvents::_getMouseInfo()
+{
+ MouseInfo mouse;
+
+ mouse.devId = mDevID;
+ mouse.joyFileD = mMouse;
+ mouse.vendor = mVendor;
+ mouse.button_map = mButtonMap;
+ mouse.axis_map = mAxisMap;
+ mouse.axis_range = mRanges;
+
+ return mouse;
+}
+
+//-------------------------------------------------------------------//
+MouseInfoList LinuxMouseEvents::_scanMouses()
+{
+ MouseInfoList mouses;
+
+ //Search through all of the event devices.. and identify which ones are mouses
+ //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_MOUSE_DEBUG
+ std::cout << "\nOpening " << s.str() << "...";
+ #endif
+ try
+ {
+ MouseInfo mouse;
+ if( EventUtils::isMouse(fd, mouse) )
+ {
+ mouses.push_back(mouse);
+ #ifdef OIS_LINUX_MOUSE_DEBUG
+ std::cout << "\n__Mouse added to list";
+ #endif
+ }
+ else
+ {
+ #ifdef OIS_LINUX_MOUSE_DEBUG
+ std::cout << "\n__Not a mouse!!";
+ #endif
+ close(fd);
+ }
+ }
+ catch(...)
+ {
+ #ifdef OIS_LINUX_MOUSE_DEBUG
+ std::cout << "\nException caught!!";
+ #endif
+ close(fd);
+ }
+ }
+
+ return mouses;
+}
+
+//-------------------------------------------------------------------//
+void LinuxMouseEvents::_clearMouses(MouseInfoList &mouses)
+{
+ for(MouseInfoList::iterator i = mouses.begin(); i != mouses.end(); ++i)
+ close(i->joyFileD);
+ mouses.clear();
+}
+
+//-------------------------------------------------------------------//
+Interface* LinuxMouseEvents::queryInterface(Interface::IType type)
+{
+ return 0;
+}