X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=src%2FInput%2FFGLinuxEventInput.cxx;h=86c04494ea4200826ca7f3e0d7d0907780ebbd04;hb=49677f512b8edaaf22c76761dbbf9c0850c79aad;hp=382a99c8aa0d2b9c5ef51997ae0d26a72e66d795;hpb=a1a610f7d5458004b8fc6fd3ff88bcec660a26f4;p=flightgear.git diff --git a/src/Input/FGLinuxEventInput.cxx b/src/Input/FGLinuxEventInput.cxx index 382a99c8a..86c04494e 100644 --- a/src/Input/FGLinuxEventInput.cxx +++ b/src/Input/FGLinuxEventInput.cxx @@ -17,18 +17,26 @@ // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// -// $Id$ #ifdef HAVE_CONFIG_H # include #endif +#include +#include +#include +#include +#include +#include +#include #include "FGLinuxEventInput.hxx" #include #include #include +#include + +#include struct TypeCode { unsigned type; @@ -238,7 +246,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 +281,11 @@ FGLinuxInputDevice::FGLinuxInputDevice() : { } +static inline bool bitSet( unsigned char * buf, unsigned bit ) +{ + return (buf[bit/sizeof(unsigned char)/8] >> (bit%(sizeof(unsigned char)*8))) & 1; +} + void FGLinuxInputDevice::Open() { if( fd != -1 ) return; @@ -280,9 +293,96 @@ 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; +/* + SG_LOG( SG_INPUT, SG_INFO, "Axis #" << i << + ": value=" << ai.value << + ": minimum=" << ai.minimum << + ": maximum=" << ai.maximum << + ": fuzz=" << ai.fuzz << + ": flat=" << ai.flat << + ": resolution=" << ai.resolution ); +*/ + + // kick an initial event + struct input_event event; + event.type = EV_ABS; + event.code = i; + event.value = ai.value; + FGLinuxEventData eventData( event, 0, 0 ); + eventData.value = Normalize( event ); + HandleEvent(eventData); + } + } + } + } + { + unsigned char mask[KEY_CNT/sizeof(unsigned char)/8]; + unsigned char flag[KEY_CNT/sizeof(unsigned char)/8]; + memset(mask,0,sizeof(mask)); + memset(flag,0,sizeof(flag)); + if( ioctl( fd, EVIOCGKEY(sizeof(flag)), flag ) == -1 || + ioctl( fd, EVIOCGBIT(EV_KEY, sizeof(mask)), mask ) == -1 ) { + SG_LOG( SG_INPUT, SG_WARN, "Can't get keys for " << devname ); + } else { + for( unsigned i = 0; i < KEY_MAX; i++ ) { + if( bitSet( mask, i ) ) { + struct input_event event; + event.type = EV_KEY; + event.code = i; + event.value = bitSet(flag,i); + FGLinuxEventData eventData( event, 0, 0 ); + HandleEvent(eventData); + } + } + } + } + { + unsigned char buf[SW_CNT/sizeof(unsigned char)/8]; + if( ioctl( fd, EVIOCGSW(sizeof(buf)), buf ) == -1 ) { + SG_LOG( SG_INPUT, SG_WARN, "Can't get switches for " << devname ); + } else { + for( unsigned i = 0; i < SW_MAX; i++ ) { + if( bitSet( buf, i ) ) { + struct input_event event; + event.type = EV_SW; + event.code = i; + event.value = 1; + FGLinuxEventData eventData( event, 0, 0 ); + HandleEvent(eventData); + } + } + } + } +} + +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 +537,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,9 +567,13 @@ 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 ); } } } } +