X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=src%2FInput%2FFGLinuxEventInput.cxx;h=03e7e05817ee7629d742810516ce84a6bfabd211;hb=d0a2fbba990c07608b813fa026126fe7ce52c552;hp=382a99c8aa0d2b9c5ef51997ae0d26a72e66d795;hpb=a1a610f7d5458004b8fc6fd3ff88bcec660a26f4;p=flightgear.git diff --git a/src/Input/FGLinuxEventInput.cxx b/src/Input/FGLinuxEventInput.cxx index 382a99c8a..03e7e0581 100644 --- a/src/Input/FGLinuxEventInput.cxx +++ b/src/Input/FGLinuxEventInput.cxx @@ -24,11 +24,15 @@ # include #endif -#include "FGLinuxEventInput.hxx" - +#include +#include +#include #include #include #include +#include +#include "FGLinuxEventInput.hxx" + struct TypeCode { unsigned type; @@ -238,7 +242,7 @@ static EventNameByType EVENT_NAME_BY_TYPE; struct ltstr { bool operator()(const char * s1, const char * s2 ) const { - return strcmp( s1, s2 ) < 0; + return string(s1).compare( s2 ) < 0; } }; @@ -273,6 +277,11 @@ FGLinuxInputDevice::FGLinuxInputDevice() : { } +static inline bool bitSet( unsigned char * buf, unsigned char bit ) +{ + return (buf[bit/sizeof(bit)/8] >> (bit%(sizeof(bit)*8))) & 1; +} + void FGLinuxInputDevice::Open() { if( fd != -1 ) return; @@ -280,9 +289,38 @@ void FGLinuxInputDevice::Open() throw exception(); } - if( GetGrab() && ioctl( fd, EVIOCGRAB, 2 ) != 0 ) { + if( GetGrab() && ioctl( fd, EVIOCGRAB, 2 ) == -1 ) { SG_LOG( SG_INPUT, SG_WARN, "Can't grab " << devname << " for exclusive access" ); } + + unsigned char buf[ABS_CNT/sizeof(unsigned char)/8]; + // get axes maximums + if( ioctl( fd, EVIOCGBIT(EV_ABS,ABS_MAX), buf ) == -1 ) { + SG_LOG( SG_INPUT, SG_WARN, "Can't get abs-axes for " << devname ); + } else { + for( unsigned i = 0; i < ABS_MAX; i++ ) { + if( bitSet( buf, i ) ) { + struct input_absinfo ai; + if( ioctl(fd, EVIOCGABS(i), &ai) == -1 ) { + SG_LOG( SG_INPUT, SG_WARN, "Can't get abs-axes maximums for " << devname ); + continue; + } + absinfo[i] = ai; + } + } + } +} + +double FGLinuxInputDevice::Normalize( struct input_event & event ) +{ + if( absinfo.count(event.code) > 0 ) { + const struct input_absinfo & ai = absinfo[(unsigned int)event.code]; + if( ai.maximum == ai.minimum ) + return 0.0; + return ((double)event.value-(double)ai.minimum)/((double)ai.maximum-(double)ai.minimum); + } else { + return (double)event.value; + } } void FGLinuxInputDevice::Close() @@ -437,7 +475,6 @@ void FGLinuxEventInput::AddHalDevice( const char * udi ) void FGLinuxEventInput::update( double dt ) { FGEventInput::update( dt ); - // index the input devices by the associated fd and prepare // the pollfd array by filling in the file descriptor struct pollfd fds[input_devices.size()]; @@ -468,6 +505,9 @@ void FGLinuxEventInput::update( double dt ) FGLinuxEventData eventData( event, dt, modifiers ); + if( event.type == EV_ABS ) + eventData.value = devicesByFd[fds[i].fd]->Normalize( event ); + // let the FGInputDevice handle the data devicesByFd[fds[i].fd]->HandleEvent( eventData ); }