00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #include "oinputsystem.h"
00030 using namespace Opie::Core;
00031
00032
00033 #include <qdir.h>
00034 #include <qfile.h>
00035
00036
00037 #include <errno.h>
00038 #include <string.h>
00039 #include <sys/fcntl.h>
00040 #include <sys/ioctl.h>
00041 #include <unistd.h>
00042
00043 #define BUFSIZE 256
00044 #define BIT_MASK( name, numbits ) \
00045 unsigned short name[ ((numbits) - 1) / (sizeof( short ) * 8) + 1 ]; \
00046 memset( name, 0, sizeof( name ) )
00047 #define BIT_TEST( bitmask, bit ) \
00048 ( bitmask[ (bit) / sizeof(short) / 8 ] & (1u << ( (bit) % (sizeof(short) * 8))) )
00049
00050
00051
00052
00053
00054 OInputSystem* OInputSystem::_instance = 0;
00055
00056 OInputSystem::OInputSystem() : QObject()
00057 {
00058 qDebug( "OInputSystem::OInputSystem()" );
00059 synchronize();
00060 }
00061
00062
00063 void OInputSystem::synchronize()
00064 {
00065 qDebug( "OInputSystem::synchronize()" );
00066 QDir devInput( "/dev/input/" );
00067 if ( devInput.exists() )
00068 {
00069 QStringList devInputFiles = devInput.entryList( QDir::System, QDir::Name );
00070 for ( QStringList::Iterator it = devInputFiles.begin(); it != devInputFiles.end(); ++it )
00071 {
00072 QString absPath = devInput.absFilePath( *it );
00073 bool isValid = OInputDevice::isValid( absPath );
00074 qDebug( "OInputSystem::synchronize() - checking if '%s' is a valid input system node... '%s' [%s]",
00075 (const char*) absPath, isValid ? "yes" : "no", isValid ? "(ok)" : strerror( errno ) );
00076 if ( isValid ) _devices.insert( *it, new OInputDevice( this, absPath ) );
00077 }
00078 }
00079 qDebug( "OInputSystem::synchronize() done" );
00080 if ( !_devices.count() )
00081 qWarning( "OInputSystem::no devices found" );
00082 }
00083
00084
00085 OInputSystem::~OInputSystem()
00086 {
00087 qDebug( "OInputSystem::~OInputSystem()" );
00088 }
00089
00090
00091 int OInputSystem::count() const
00092 {
00093 return _devices.count();
00094 }
00095
00096
00097 OInputDevice* OInputSystem::device( const QString& device ) const
00098 {
00099 return _devices[device];
00100 }
00101
00102
00103 OInputSystem* OInputSystem::instance()
00104 {
00105 if ( !_instance ) _instance = new OInputSystem();
00106 return _instance;
00107 }
00108
00109
00110 OInputSystem::DeviceIterator OInputSystem::iterator() const
00111 {
00112 return OInputSystem::DeviceIterator( _devices );
00113 }
00114
00115
00116
00117
00118
00119 OInputDevice::OInputDevice( QObject* parent, const char* name ) : QObject( parent, name )
00120 {
00121 qDebug( "OInputDevice::OInputDevice( '%s' )", name );
00122
00123 _fd = ::open( name, O_RDONLY );
00124 if ( _fd == -1 )
00125 {
00126 qDebug( "OInputDevice::OInputDevice() - Warning: couldn't open %s (%s)", name, strerror( errno ) );
00127 }
00128 }
00129
00130
00131 OInputDevice::~OInputDevice()
00132 {
00133 qDebug( "OInputDevice::~OInputDevice()" );
00134 }
00135
00136
00137 QString OInputDevice::identity() const
00138 {
00139 char buf[BUFSIZE] = "<unknown>";
00140 ::ioctl( _fd, EVIOCGNAME(sizeof buf), buf );
00141 return buf;
00142 }
00143
00144
00145 QString OInputDevice::path() const
00146 {
00147 char buf[BUFSIZE] = "<unknown>";
00148 ::ioctl( _fd, EVIOCGPHYS(sizeof buf), buf );
00149 return buf;
00150 }
00151
00152
00153 QString OInputDevice::uniq() const
00154 {
00155 char buf[BUFSIZE] = "<unknown>";
00156 ::ioctl( _fd, EVIOCGUNIQ(sizeof buf), buf );
00157 return buf;
00158 }
00159
00160
00161 bool OInputDevice::hasFeature( Feature bit ) const
00162 {
00163 BIT_MASK( features, EV_MAX );
00164
00165 if( ioctl( _fd, EVIOCGBIT( 0, EV_MAX ), features) < 0 )
00166 {
00167 perror( "EVIOCGBIT" );
00168 return false;
00169 }
00170 else
00171 return BIT_TEST( features, bit );
00172 }
00173
00174
00175 bool OInputDevice::isHeld( Key bit ) const
00176 {
00177 BIT_MASK( keys, KEY_MAX );
00178
00179 if( ioctl( _fd, EVIOCGKEY( sizeof(keys) ), keys ) < 0 )
00180 {
00181 perror( "EVIOCGKEY" );
00182 return false;
00183 }
00184 else
00185 {
00186 return BIT_TEST( keys, bit );
00187 }
00188 }
00189
00190
00191 bool OInputDevice::isHeld( Switch bit ) const
00192 {
00193 BIT_MASK( switches, SW_MAX );
00194
00195 if( ioctl( _fd, EVIOCGSW( sizeof(switches) ), switches ) < 0 )
00196 {
00197 perror( "EVIOCGSW" );
00198 return false;
00199 }
00200 else
00201 {
00202 return BIT_TEST( switches, bit );
00203 }
00204 }
00205
00206
00207 QString OInputDevice::globalKeyMask() const
00208 {
00209 BIT_MASK( keys, KEY_MAX );
00210
00211 if( ioctl( _fd, EVIOCGKEY( sizeof(keys) ), keys ) < 0 )
00212 {
00213 perror( "EVIOCGKEY" );
00214 return QString::null;
00215 }
00216 else
00217 {
00218 QString keymask;
00219 for ( int i = 0; i < KEY_MAX; ++i )
00220 {
00221 if ( BIT_TEST( keys, i ) ) keymask.append( QString().sprintf( "%0d, ", i ) );
00222 }
00223 return keymask;
00224
00225 }
00226 }
00227
00228
00229 QString OInputDevice::globalSwitchMask() const
00230 {
00231 BIT_MASK( switches, SW_MAX );
00232
00233 if( ioctl( _fd, EVIOCGSW( sizeof(switches) ), switches ) < 0 )
00234 {
00235 perror( "EVIOCGSW" );
00236 return QString::null;
00237 }
00238 else
00239 {
00240 QString switchmask;
00241 for ( int i = 0; i < SW_MAX; ++i )
00242 {
00243 if ( BIT_TEST( switches, i ) ) switchmask.append( QString().sprintf( "%0d, ", i ) );
00244 }
00245 return switchmask;
00246
00247 }
00248 }
00249
00250
00251 bool OInputDevice::isValid( const QString& path )
00252 {
00253 char buf[BUFSIZE] = "<unknown>";
00254 int fd = ::open( (const char*) path, O_RDONLY );
00255 if ( fd < 0 ) return false;
00256 int res = ::ioctl( fd, EVIOCGNAME(sizeof buf), buf );
00257 ::close( fd );
00258 return res >= 0;
00259 }
00260