| [1505] | 1 | /* | 
|---|
|  | 2 | The zlib/libpng License | 
|---|
|  | 3 |  | 
|---|
|  | 4 | Copyright (c) 2005-2007 Phillip Castaneda (pjcast -- www.wreckedgames.com) | 
|---|
|  | 5 |  | 
|---|
|  | 6 | This software is provided 'as-is', without any express or implied warranty. In no event will | 
|---|
|  | 7 | the authors be held liable for any damages arising from the use of this software. | 
|---|
|  | 8 |  | 
|---|
|  | 9 | Permission is granted to anyone to use this software for any purpose, including commercial | 
|---|
|  | 10 | applications, and to alter it and redistribute it freely, subject to the following | 
|---|
|  | 11 | restrictions: | 
|---|
|  | 12 |  | 
|---|
|  | 13 | 1. The origin of this software must not be misrepresented; you must not claim that | 
|---|
|  | 14 | you wrote the original software. If you use this software in a product, | 
|---|
|  | 15 | an acknowledgment in the product documentation would be appreciated but is | 
|---|
|  | 16 | not required. | 
|---|
|  | 17 |  | 
|---|
|  | 18 | 2. Altered source versions must be plainly marked as such, and must not be | 
|---|
|  | 19 | misrepresented as being the original software. | 
|---|
|  | 20 |  | 
|---|
|  | 21 | 3. This notice may not be removed or altered from any source distribution. | 
|---|
|  | 22 | */ | 
|---|
|  | 23 | #include "linux/EventHelpers.h" | 
|---|
|  | 24 | #include "linux/LinuxPrereqs.h" | 
|---|
|  | 25 | #include "linux/LinuxForceFeedback.h" | 
|---|
|  | 26 | #include "OISException.h" | 
|---|
|  | 27 | #include "OISJoyStick.h" | 
|---|
|  | 28 |  | 
|---|
|  | 29 | #include <linux/input.h> | 
|---|
|  | 30 | #include <cstring> | 
|---|
|  | 31 |  | 
|---|
|  | 32 | //#define OIS_LINUX_JOY_DEBUG | 
|---|
|  | 33 |  | 
|---|
|  | 34 | #ifdef OIS_LINUX_JOY_DEBUG | 
|---|
|  | 35 | # include <iostream> | 
|---|
|  | 36 | #endif | 
|---|
|  | 37 |  | 
|---|
| [5695] | 38 | // Fixes for missing macros in input.h | 
|---|
|  | 39 | #ifndef FF_EFFECT_MIN | 
|---|
|  | 40 | #define FF_EFFECT_MIN FF_RUMBLE | 
|---|
|  | 41 | #endif | 
|---|
|  | 42 | #ifndef FF_EFFECT_MAX | 
|---|
|  | 43 | #define FF_EFFECT_MAX FF_RAMP | 
|---|
|  | 44 | #endif | 
|---|
|  | 45 | #ifndef FF_WAVEFORM_MIN | 
|---|
|  | 46 | #define FF_WAVEFORM_MIN FF_SQUARE | 
|---|
|  | 47 | #endif | 
|---|
|  | 48 | #ifndef FF_WAVEFORM_MAX | 
|---|
|  | 49 | #define FF_WAVEFORM_MAX FF_CUSTOM | 
|---|
|  | 50 | #endif | 
|---|
|  | 51 |  | 
|---|
|  | 52 | using namespace std; | 
|---|
| [1505] | 53 | using namespace OIS; | 
|---|
|  | 54 |  | 
|---|
|  | 55 | class DeviceComponentInfo | 
|---|
|  | 56 | { | 
|---|
|  | 57 | public: | 
|---|
| [5695] | 58 | vector<int> buttons, relAxes, absAxes, hats; | 
|---|
| [1505] | 59 | }; | 
|---|
|  | 60 |  | 
|---|
| [5695] | 61 | bool inline isBitSet(unsigned char bits[], unsigned int bit) | 
|---|
| [1505] | 62 | { | 
|---|
| [5695] | 63 | return (bits[(bit)/(sizeof(unsigned char)*8)] >> ((bit)%(sizeof(unsigned char)*8))) & 1; | 
|---|
| [1505] | 64 | } | 
|---|
| [5695] | 65 |  | 
|---|
| [1505] | 66 | //-----------------------------------------------------------------------------// | 
|---|
|  | 67 | DeviceComponentInfo getComponentInfo( int deviceID ) | 
|---|
|  | 68 | { | 
|---|
| [5695] | 69 | unsigned char ev_bits[1 + EV_MAX/8/sizeof(unsigned char)]; | 
|---|
|  | 70 | memset( ev_bits, 0, sizeof(ev_bits) ); | 
|---|
| [1505] | 71 |  | 
|---|
| [5695] | 72 | //Read "all" (hence 0) components of the device | 
|---|
|  | 73 | #ifdef OIS_LINUX_JOY_DEBUG | 
|---|
|  | 74 | cout << "EventUtils::getComponentInfo(" << deviceID | 
|---|
|  | 75 | << ") : Reading device events features" << endl; | 
|---|
|  | 76 | #endif | 
|---|
|  | 77 | if (ioctl(deviceID, EVIOCGBIT(0, sizeof(ev_bits)), ev_bits) == -1) | 
|---|
|  | 78 | OIS_EXCEPT( E_General, "Could not read device events features"); | 
|---|
|  | 79 |  | 
|---|
| [1505] | 80 | DeviceComponentInfo components; | 
|---|
|  | 81 |  | 
|---|
|  | 82 | for (int i = 0; i < EV_MAX; i++) | 
|---|
|  | 83 | { | 
|---|
| [5695] | 84 | if( isBitSet(ev_bits, i) ) | 
|---|
| [1505] | 85 | { | 
|---|
| [5695] | 86 | // Absolute axis. | 
|---|
|  | 87 | if(i == EV_ABS) | 
|---|
| [1505] | 88 | { | 
|---|
| [5695] | 89 | unsigned char abs_bits[1 + ABS_MAX/8/sizeof(unsigned char)]; | 
|---|
|  | 90 | memset( abs_bits, 0, sizeof(abs_bits) ); | 
|---|
|  | 91 |  | 
|---|
|  | 92 | #ifdef OIS_LINUX_JOY_DEBUG | 
|---|
|  | 93 | cout << "EventUtils::getComponentInfo(" << deviceID | 
|---|
|  | 94 | << ") : Reading device absolute axis features" << endl; | 
|---|
|  | 95 | #endif | 
|---|
|  | 96 |  | 
|---|
|  | 97 | if (ioctl(deviceID, EVIOCGBIT(i, sizeof(abs_bits)), abs_bits) == -1) | 
|---|
|  | 98 | OIS_EXCEPT( E_General, "Could not read device absolute axis features"); | 
|---|
|  | 99 |  | 
|---|
|  | 100 | for (int j = 0; j < ABS_MAX; j++) | 
|---|
| [1505] | 101 | { | 
|---|
| [5695] | 102 | if( isBitSet(abs_bits, j) ) | 
|---|
| [1505] | 103 | { | 
|---|
|  | 104 | //input_absinfo abInfo; | 
|---|
|  | 105 | //ioctl( fd, EVIOCGABS(j), abInfo ); | 
|---|
|  | 106 | if( j >= ABS_HAT0X && j <= ABS_HAT3Y ) | 
|---|
|  | 107 | { | 
|---|
|  | 108 | components.hats.push_back(j); | 
|---|
|  | 109 | } | 
|---|
|  | 110 | else | 
|---|
|  | 111 | { | 
|---|
|  | 112 | components.absAxes.push_back(j); | 
|---|
|  | 113 | //input_absinfo absinfo; | 
|---|
|  | 114 | //ioctl(deviceID, EVIOCGABS(j), &absinfo); | 
|---|
|  | 115 | //We cannot actually change these values :| | 
|---|
|  | 116 | //absinfo.minimum = JoyStick::MIN_AXIS; | 
|---|
|  | 117 | //absinfo.maximum = JoyStick::MAX_AXIS; | 
|---|
|  | 118 | //ioctl(deviceID, EVIOCSABS(j), &absinfo); | 
|---|
|  | 119 | } | 
|---|
|  | 120 | } | 
|---|
| [5695] | 121 | } | 
|---|
|  | 122 | } | 
|---|
|  | 123 | else if(i == EV_REL) | 
|---|
|  | 124 | { | 
|---|
|  | 125 | unsigned char rel_bits[1 + REL_MAX/8/sizeof(unsigned char)]; | 
|---|
|  | 126 | memset( rel_bits, 0, sizeof(rel_bits) ); | 
|---|
|  | 127 |  | 
|---|
|  | 128 | #ifdef OIS_LINUX_JOY_DEBUG | 
|---|
|  | 129 | cout << "EventUtils::getComponentInfo(" << deviceID | 
|---|
|  | 130 | << ") : Reading device relative axis features" << endl; | 
|---|
|  | 131 | #endif | 
|---|
|  | 132 |  | 
|---|
|  | 133 | if (ioctl(deviceID, EVIOCGBIT(i, sizeof(rel_bits)), rel_bits) == -1) | 
|---|
|  | 134 | OIS_EXCEPT( E_General, "Could not read device relative axis features"); | 
|---|
|  | 135 |  | 
|---|
|  | 136 | for (int j = 0; j < REL_MAX; j++) | 
|---|
|  | 137 | { | 
|---|
|  | 138 | if( isBitSet(rel_bits, j) ) | 
|---|
| [1505] | 139 | { | 
|---|
| [5695] | 140 | components.relAxes.push_back(j); | 
|---|
| [1505] | 141 | } | 
|---|
| [5695] | 142 | } | 
|---|
|  | 143 | } | 
|---|
|  | 144 | else if(i == EV_KEY) | 
|---|
|  | 145 | { | 
|---|
|  | 146 | unsigned char key_bits[1 + KEY_MAX/8/sizeof(unsigned char)]; | 
|---|
|  | 147 | memset( key_bits, 0, sizeof(key_bits) ); | 
|---|
|  | 148 |  | 
|---|
|  | 149 | #ifdef OIS_LINUX_JOY_DEBUG | 
|---|
|  | 150 | cout << "EventUtils::getComponentInfo(" << deviceID | 
|---|
|  | 151 | << ") : Reading device buttons features" << endl; | 
|---|
|  | 152 | #endif | 
|---|
|  | 153 |  | 
|---|
|  | 154 | if (ioctl(deviceID, EVIOCGBIT(i, sizeof(key_bits)), key_bits) == -1) | 
|---|
|  | 155 | OIS_EXCEPT( E_General, "Could not read device buttons features"); | 
|---|
|  | 156 |  | 
|---|
|  | 157 | for (int j = 0; j < KEY_MAX; j++) | 
|---|
|  | 158 | { | 
|---|
|  | 159 | if( isBitSet(key_bits, j) ) | 
|---|
| [1505] | 160 | { | 
|---|
| [5695] | 161 | components.buttons.push_back(j); | 
|---|
| [1505] | 162 | } | 
|---|
|  | 163 | } | 
|---|
|  | 164 | } | 
|---|
|  | 165 | } | 
|---|
|  | 166 | } | 
|---|
|  | 167 |  | 
|---|
|  | 168 | return components; | 
|---|
|  | 169 | } | 
|---|
|  | 170 |  | 
|---|
|  | 171 | //-----------------------------------------------------------------------------// | 
|---|
|  | 172 | bool EventUtils::isJoyStick( int deviceID, JoyStickInfo &js ) | 
|---|
|  | 173 | { | 
|---|
| [5695] | 174 | if( deviceID == -1 ) | 
|---|
|  | 175 | OIS_EXCEPT( E_General, "Error with File Descriptor" ); | 
|---|
| [1505] | 176 |  | 
|---|
|  | 177 | DeviceComponentInfo info = getComponentInfo( deviceID ); | 
|---|
|  | 178 |  | 
|---|
|  | 179 | int buttons = 0; | 
|---|
|  | 180 | bool joyButtonFound = false; | 
|---|
|  | 181 | js.button_map.clear(); | 
|---|
|  | 182 |  | 
|---|
|  | 183 | #ifdef OIS_LINUX_JOY_DEBUG | 
|---|
| [5695] | 184 | cout << endl << "Displaying ButtonMapping Status:" << endl; | 
|---|
| [1505] | 185 | #endif | 
|---|
| [5695] | 186 | for(vector<int>::iterator i = info.buttons.begin(), e = info.buttons.end(); i != e; ++i ) | 
|---|
| [1505] | 187 | { | 
|---|
|  | 188 | //Check to ensure we find at least one joy only button | 
|---|
| [5695] | 189 | if( (*i >= BTN_JOYSTICK && *i < BTN_GAMEPAD) | 
|---|
|  | 190 | || (*i >= BTN_GAMEPAD && *i < BTN_DIGI) | 
|---|
|  | 191 | || (*i >= BTN_WHEEL && *i < KEY_OK) ) | 
|---|
| [1505] | 192 | joyButtonFound = true; | 
|---|
|  | 193 |  | 
|---|
|  | 194 | js.button_map[*i] = buttons++; | 
|---|
|  | 195 |  | 
|---|
|  | 196 | #ifdef OIS_LINUX_JOY_DEBUG | 
|---|
| [5695] | 197 | cout << "Button Mapping ID (hex): " << hex << *i | 
|---|
|  | 198 | << " OIS Button Num: " << dec << buttons-1 << endl; | 
|---|
| [1505] | 199 | #endif | 
|---|
|  | 200 | } | 
|---|
| [5695] | 201 | #ifdef OIS_LINUX_JOY_DEBUG | 
|---|
|  | 202 | cout << endl; | 
|---|
|  | 203 | #endif | 
|---|
| [1505] | 204 |  | 
|---|
|  | 205 | //Joy Buttons found, so it must be a joystick or pad | 
|---|
|  | 206 | if( joyButtonFound ) | 
|---|
|  | 207 | { | 
|---|
|  | 208 | js.joyFileD = deviceID; | 
|---|
|  | 209 | js.vendor = getName(deviceID); | 
|---|
|  | 210 | js.buttons = buttons; | 
|---|
|  | 211 | js.axes = info.relAxes.size() + info.absAxes.size(); | 
|---|
|  | 212 | js.hats = info.hats.size(); | 
|---|
| [5695] | 213 | #ifdef OIS_LINUX_JOY_DEBUG | 
|---|
|  | 214 | cout << endl << "Device name:" << js.vendor << endl; | 
|---|
|  | 215 | cout << "Device unique Id:" << getUniqueId(deviceID) << endl; | 
|---|
|  | 216 | cout << "Device physical location:" << getPhysicalLocation(deviceID) << endl; | 
|---|
|  | 217 | #endif | 
|---|
| [1505] | 218 |  | 
|---|
|  | 219 | //Map the Axes | 
|---|
|  | 220 | #ifdef OIS_LINUX_JOY_DEBUG | 
|---|
| [5695] | 221 | cout << endl << "Displaying AxisMapping Status:" << endl; | 
|---|
| [1505] | 222 | #endif | 
|---|
|  | 223 | int axes = 0; | 
|---|
| [5695] | 224 | for(vector<int>::iterator i = info.absAxes.begin(), e = info.absAxes.end(); i != e; ++i ) | 
|---|
| [1505] | 225 | { | 
|---|
|  | 226 | js.axis_map[*i] = axes; | 
|---|
|  | 227 |  | 
|---|
| [5695] | 228 | #ifdef OIS_LINUX_JOY_DEBUG | 
|---|
|  | 229 | cout << "EventUtils::isJoyStick(" << deviceID | 
|---|
|  | 230 | << ") : Reading device absolute axis #" << *i << " features" << endl; | 
|---|
|  | 231 | #endif | 
|---|
|  | 232 |  | 
|---|
| [1505] | 233 | input_absinfo absinfo; | 
|---|
| [5695] | 234 | if (ioctl(deviceID, EVIOCGABS(*i), &absinfo) == -1) | 
|---|
|  | 235 | OIS_EXCEPT( E_General, "Could not read device absolute axis features"); | 
|---|
| [1505] | 236 | js.axis_range[axes] = Range(absinfo.minimum, absinfo.maximum); | 
|---|
|  | 237 |  | 
|---|
|  | 238 | #ifdef OIS_LINUX_JOY_DEBUG | 
|---|
| [5695] | 239 | cout << "Axis Mapping ID (hex): " << hex << *i | 
|---|
|  | 240 | << " OIS Axis Num: " << dec << axes << endl; | 
|---|
| [1505] | 241 | #endif | 
|---|
|  | 242 |  | 
|---|
|  | 243 | ++axes; | 
|---|
|  | 244 | } | 
|---|
|  | 245 | } | 
|---|
|  | 246 |  | 
|---|
|  | 247 | return joyButtonFound; | 
|---|
|  | 248 | } | 
|---|
|  | 249 |  | 
|---|
|  | 250 | //-----------------------------------------------------------------------------// | 
|---|
| [5695] | 251 | string EventUtils::getName( int deviceID ) | 
|---|
| [1505] | 252 | { | 
|---|
| [5695] | 253 | #ifdef OIS_LINUX_JOY_DEBUG | 
|---|
|  | 254 | cout << "EventUtils::getName(" << deviceID | 
|---|
|  | 255 | << ") : Reading device name" << endl; | 
|---|
|  | 256 | #endif | 
|---|
|  | 257 |  | 
|---|
| [1505] | 258 | char name[OIS_DEVICE_NAME]; | 
|---|
| [5695] | 259 | if (ioctl(deviceID, EVIOCGNAME(OIS_DEVICE_NAME), name) == -1) | 
|---|
|  | 260 | OIS_EXCEPT( E_General, "Could not read device name"); | 
|---|
|  | 261 | return string(name); | 
|---|
| [1505] | 262 | } | 
|---|
|  | 263 |  | 
|---|
|  | 264 | //-----------------------------------------------------------------------------// | 
|---|
| [5695] | 265 | string EventUtils::getUniqueId( int deviceID ) | 
|---|
|  | 266 | { | 
|---|
|  | 267 | #ifdef OIS_LINUX_JOY_DEBUG | 
|---|
|  | 268 | cout << "EventUtils::getUniqueId(" << deviceID | 
|---|
|  | 269 | << ") : Reading device unique Id" << endl; | 
|---|
|  | 270 | #endif | 
|---|
|  | 271 |  | 
|---|
|  | 272 | #define OIS_DEVICE_UNIQUE_ID 128 | 
|---|
|  | 273 | char uId[OIS_DEVICE_UNIQUE_ID]; | 
|---|
|  | 274 | if (ioctl(deviceID, EVIOCGUNIQ(OIS_DEVICE_UNIQUE_ID), uId) == -1) | 
|---|
|  | 275 | OIS_EXCEPT( E_General, "Could not read device unique Id"); | 
|---|
|  | 276 | return string(uId); | 
|---|
|  | 277 | } | 
|---|
|  | 278 |  | 
|---|
|  | 279 | //-----------------------------------------------------------------------------// | 
|---|
|  | 280 | string EventUtils::getPhysicalLocation( int deviceID ) | 
|---|
|  | 281 | { | 
|---|
|  | 282 | #ifdef OIS_LINUX_JOY_DEBUG | 
|---|
|  | 283 | cout << "EventUtils::getPhysicalLocation(" << deviceID | 
|---|
|  | 284 | << ") : Reading device physical location" << endl; | 
|---|
|  | 285 | #endif | 
|---|
|  | 286 |  | 
|---|
|  | 287 | #define OIS_DEVICE_PHYSICAL_LOCATION 128 | 
|---|
|  | 288 | char physLoc[OIS_DEVICE_PHYSICAL_LOCATION]; | 
|---|
|  | 289 | if (ioctl(deviceID, EVIOCGPHYS(OIS_DEVICE_PHYSICAL_LOCATION), physLoc) == -1) | 
|---|
|  | 290 | OIS_EXCEPT( E_General, "Could not read device physical location"); | 
|---|
|  | 291 | return string(physLoc); | 
|---|
|  | 292 | } | 
|---|
|  | 293 |  | 
|---|
|  | 294 | //-----------------------------------------------------------------------------// | 
|---|
| [1505] | 295 | void EventUtils::enumerateForceFeedback( int deviceID, LinuxForceFeedback** ff ) | 
|---|
|  | 296 | { | 
|---|
|  | 297 | //Linux Event to OIS Event Mappings | 
|---|
| [5695] | 298 | map<int, Effect::EType> typeMap; | 
|---|
| [1505] | 299 | typeMap[FF_CONSTANT] = Effect::Constant; | 
|---|
|  | 300 | typeMap[FF_RAMP]     = Effect::Ramp; | 
|---|
|  | 301 | typeMap[FF_SPRING]   = Effect::Spring; | 
|---|
|  | 302 | typeMap[FF_FRICTION] = Effect::Friction; | 
|---|
|  | 303 | typeMap[FF_SQUARE]   = Effect::Square; | 
|---|
|  | 304 | typeMap[FF_TRIANGLE] = Effect::Triangle; | 
|---|
|  | 305 | typeMap[FF_SINE]     = Effect::Sine; | 
|---|
|  | 306 | typeMap[FF_SAW_UP]   = Effect::SawToothUp; | 
|---|
|  | 307 | typeMap[FF_SAW_DOWN] = Effect::SawToothDown; | 
|---|
|  | 308 | typeMap[FF_DAMPER]   = Effect::Damper; | 
|---|
|  | 309 | typeMap[FF_INERTIA]  = Effect::Inertia; | 
|---|
|  | 310 | typeMap[FF_CUSTOM]   = Effect::Custom; | 
|---|
|  | 311 |  | 
|---|
| [5695] | 312 | map<int, Effect::EForce> forceMap; | 
|---|
| [1505] | 313 | forceMap[FF_CONSTANT] = Effect::ConstantForce; | 
|---|
| [5695] | 314 | forceMap[FF_RAMP]     = Effect::RampForce; | 
|---|
|  | 315 | forceMap[FF_SPRING]   = Effect::ConditionalForce; | 
|---|
|  | 316 | forceMap[FF_FRICTION] = Effect::ConditionalForce; | 
|---|
|  | 317 | forceMap[FF_SQUARE]   = Effect::PeriodicForce; | 
|---|
|  | 318 | forceMap[FF_TRIANGLE] = Effect::PeriodicForce; | 
|---|
|  | 319 | forceMap[FF_SINE]     = Effect::PeriodicForce; | 
|---|
|  | 320 | forceMap[FF_SAW_UP]   = Effect::PeriodicForce; | 
|---|
|  | 321 | forceMap[FF_SAW_DOWN] = Effect::PeriodicForce; | 
|---|
|  | 322 | forceMap[FF_DAMPER]   = Effect::ConditionalForce; | 
|---|
|  | 323 | forceMap[FF_INERTIA]  = Effect::ConditionalForce; | 
|---|
|  | 324 | forceMap[FF_CUSTOM]   = Effect::CustomForce; | 
|---|
| [1505] | 325 |  | 
|---|
|  | 326 | //Remove any previously existing memory and create fresh | 
|---|
|  | 327 | removeForceFeedback( ff ); | 
|---|
| [5695] | 328 | *ff = new LinuxForceFeedback(deviceID); | 
|---|
| [1505] | 329 |  | 
|---|
| [5695] | 330 | //Read overall force feedback features | 
|---|
|  | 331 | unsigned char ff_bits[1 + FF_MAX/8/sizeof(unsigned char)]; | 
|---|
|  | 332 | memset(ff_bits, 0, sizeof(ff_bits)); | 
|---|
| [1505] | 333 |  | 
|---|
| [5695] | 334 | #ifdef OIS_LINUX_JOY_DEBUG | 
|---|
|  | 335 | cout << "EventUtils::enumerateForceFeedback(" << deviceID | 
|---|
|  | 336 | << ") : Reading device force feedback features" << endl; | 
|---|
|  | 337 | #endif | 
|---|
| [1505] | 338 |  | 
|---|
| [5695] | 339 | if (ioctl(deviceID, EVIOCGBIT(EV_FF, sizeof(ff_bits)), ff_bits) == -1) | 
|---|
|  | 340 | OIS_EXCEPT( E_General, "Could not read device force feedback features"); | 
|---|
|  | 341 |  | 
|---|
|  | 342 |  | 
|---|
|  | 343 | #ifdef OIS_LINUX_JOY_DEBUG | 
|---|
|  | 344 | cout << "FF bits: " << hex; | 
|---|
|  | 345 | for (int i = 0; i < sizeof(ff_bits); i++) | 
|---|
|  | 346 | cout << (int)ff_bits[i]; | 
|---|
|  | 347 | cout << endl << dec; | 
|---|
|  | 348 | #endif | 
|---|
|  | 349 |  | 
|---|
| [1505] | 350 | //FF Axes | 
|---|
| [5695] | 351 | //if( isBitSet(ff_bits, ABS_X) ) //X Axis | 
|---|
|  | 352 | //if( isBitSet(ff_bits, ABS_Y) ) //Y Axis | 
|---|
|  | 353 | //if( isBitSet(ff_bits, ABS_WHEEL) ) //Wheel | 
|---|
| [1505] | 354 |  | 
|---|
|  | 355 | //FF Effects | 
|---|
| [5695] | 356 | for( int effect = FF_EFFECT_MIN; effect <= FF_WAVEFORM_MAX; effect++ ) | 
|---|
| [1505] | 357 | { | 
|---|
| [5695] | 358 | // The RUMBLE force type is ignored, as periodic force one is more powerfull. | 
|---|
|  | 359 | // The PERIODIC force type is processed later, for each associated periodic effect type. | 
|---|
|  | 360 | if (effect == FF_RUMBLE || effect == FF_PERIODIC) | 
|---|
|  | 361 | continue; | 
|---|
|  | 362 |  | 
|---|
|  | 363 | if(isBitSet(ff_bits, effect)) | 
|---|
| [1505] | 364 | { | 
|---|
| [5695] | 365 | #ifdef OIS_LINUX_JOY_DEBUG | 
|---|
|  | 366 | cout << "  Effect Type: " << Effect::getEffectTypeName(typeMap[effect]) << endl; | 
|---|
|  | 367 | #endif | 
|---|
|  | 368 |  | 
|---|
|  | 369 | (*ff)->_addEffectTypes( forceMap[effect], typeMap[effect] ); | 
|---|
| [1505] | 370 | } | 
|---|
|  | 371 | } | 
|---|
|  | 372 |  | 
|---|
| [5695] | 373 | //FF device properties | 
|---|
|  | 374 | if (isBitSet(ff_bits, FF_GAIN)) | 
|---|
|  | 375 | (*ff)->_setGainSupport(true); | 
|---|
|  | 376 |  | 
|---|
|  | 377 | if (isBitSet(ff_bits, FF_AUTOCENTER)) | 
|---|
|  | 378 | (*ff)->_setAutoCenterSupport(true); | 
|---|
|  | 379 |  | 
|---|
| [1505] | 380 | //Check to see if any effects were added, else destroy the pointer | 
|---|
|  | 381 | const ForceFeedback::SupportedEffectList &list = (*ff)->getSupportedEffects(); | 
|---|
|  | 382 | if( list.size() == 0 ) | 
|---|
|  | 383 | removeForceFeedback( ff ); | 
|---|
|  | 384 | } | 
|---|
|  | 385 |  | 
|---|
|  | 386 | //-----------------------------------------------------------------------------// | 
|---|
|  | 387 | void EventUtils::removeForceFeedback( LinuxForceFeedback** ff ) | 
|---|
|  | 388 | { | 
|---|
|  | 389 | delete *ff; | 
|---|
|  | 390 | *ff = 0; | 
|---|
|  | 391 | } | 
|---|