evdevInputDevice.cxx 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997
  1. /**
  2. * PANDA 3D SOFTWARE
  3. * Copyright (c) Carnegie Mellon University. All rights reserved.
  4. *
  5. * All use of this software is subject to the terms of the revised BSD
  6. * license. You should have received a copy of this license along
  7. * with this source code in a file named "LICENSE."
  8. *
  9. * @file evdevInputDevice.cxx
  10. * @author rdb
  11. * @date 2015-08-24
  12. */
  13. #include "evdevInputDevice.h"
  14. #ifdef PHAVE_LINUX_INPUT_H
  15. #include "gamepadButton.h"
  16. #include "keyboardButton.h"
  17. #include "mouseButton.h"
  18. #include "linuxInputDeviceManager.h"
  19. #include <fcntl.h>
  20. #include <linux/input.h>
  21. #ifndef BTN_DPAD_UP
  22. #define BTN_DPAD_UP 0x220
  23. #define BTN_DPAD_DOWN 0x221
  24. #define BTN_DPAD_LEFT 0x222
  25. #define BTN_DPAD_RIGHT 0x223
  26. #endif
  27. // Android introduces these in API level 21.
  28. #ifndef BTN_TRIGGER_HAPPY
  29. #define BTN_TRIGGER_HAPPY 0x2c0
  30. #define BTN_TRIGGER_HAPPY1 0x2c0
  31. #define BTN_TRIGGER_HAPPY2 0x2c1
  32. #define BTN_TRIGGER_HAPPY3 0x2c2
  33. #define BTN_TRIGGER_HAPPY4 0x2c3
  34. #endif
  35. #define test_bit(bit, array) ((array)[(bit)>>3] & (1<<((bit)&7)))
  36. enum QuirkBits {
  37. // Right stick uses Z and Rz inputs.
  38. QB_rstick_from_z = 1,
  39. // Throttle goes from -1 to 1 rather than from 0 to 1.
  40. QB_centered_throttle = 2,
  41. // Throttle is reversed.
  42. QB_reversed_throttle = 4,
  43. // Only consider the device "connected" if all axes are non-zero.
  44. QB_connect_if_nonzero = 8,
  45. // ABS_THROTTLE maps to rudder
  46. QB_rudder_from_throttle = 16,
  47. };
  48. static const struct DeviceMapping {
  49. unsigned short vendor;
  50. unsigned short product;
  51. InputDevice::DeviceClass device_class;
  52. int quirks;
  53. } mapping_presets[] = {
  54. // NVIDIA Shield Controller
  55. {0x0955, 0x7214, InputDevice::DeviceClass::gamepad, QB_rstick_from_z},
  56. // T.Flight Hotas X
  57. {0x044f, 0xb108, InputDevice::DeviceClass::flight_stick, QB_centered_throttle | QB_reversed_throttle | QB_rudder_from_throttle},
  58. // Xbox 360 Wireless Controller
  59. {0x045e, 0x0719, InputDevice::DeviceClass::gamepad, QB_connect_if_nonzero},
  60. // Jess Tech Colour Rumble Pad
  61. {0x0f30, 0x0111, InputDevice::DeviceClass::gamepad, 0},
  62. // 3Dconnexion Space Traveller 3D Mouse
  63. {0x046d, 0xc623, InputDevice::DeviceClass::spatial_mouse, 0},
  64. // 3Dconnexion Space Pilot 3D Mouse
  65. {0x046d, 0xc625, InputDevice::DeviceClass::spatial_mouse, 0},
  66. // 3Dconnexion Space Navigator 3D Mouse
  67. {0x046d, 0xc626, InputDevice::DeviceClass::spatial_mouse, 0},
  68. // 3Dconnexion Space Explorer 3D Mouse
  69. {0x046d, 0xc627, InputDevice::DeviceClass::spatial_mouse, 0},
  70. // 3Dconnexion Space Navigator for Notebooks
  71. {0x046d, 0xc628, InputDevice::DeviceClass::spatial_mouse, 0},
  72. // 3Dconnexion SpacePilot Pro 3D Mouse
  73. {0x046d, 0xc629, InputDevice::DeviceClass::spatial_mouse, 0},
  74. // 3Dconnexion Space Mouse Pro
  75. {0x046d, 0xc62b, InputDevice::DeviceClass::spatial_mouse, 0},
  76. {0},
  77. };
  78. TypeHandle EvdevInputDevice::_type_handle;
  79. /**
  80. * Creates a new device representing the evdev device with the given index.
  81. */
  82. EvdevInputDevice::
  83. EvdevInputDevice(LinuxInputDeviceManager *manager, size_t index) :
  84. _manager(manager),
  85. _index(index),
  86. _fd(-1),
  87. _can_write(false),
  88. _ff_id(-1),
  89. _ff_playing(false),
  90. _ff_strong(-1),
  91. _ff_weak(-1),
  92. _dpad_x_axis(-1),
  93. _dpad_y_axis(-1),
  94. _dpad_left_button(-1),
  95. _dpad_up_button(-1),
  96. _ltrigger_code(-1),
  97. _rtrigger_code(-1) {
  98. char path[64];
  99. sprintf(path, "/dev/input/event%zd", index);
  100. _fd = open(path, O_RDWR | O_NONBLOCK);
  101. if (_fd >= 0) {
  102. _can_write = true;
  103. } else {
  104. // On failure, open device as read-only.
  105. _fd = open(path, O_RDONLY | O_NONBLOCK);
  106. }
  107. if (_fd >= 0) {
  108. init_device();
  109. } else {
  110. _is_connected = false;
  111. device_cat.error()
  112. << "Opening raw input device: " << strerror(errno) << " " << path << "\n";
  113. }
  114. }
  115. /**
  116. *
  117. */
  118. EvdevInputDevice::
  119. ~EvdevInputDevice() {
  120. if (_fd != -1) {
  121. if (_ff_id != -1) {
  122. // Remove force-feedback effect.
  123. do_set_vibration(0, 0);
  124. ioctl(_fd, EVIOCRMFF, _ff_id);
  125. _ff_id = -1;
  126. }
  127. close(_fd);
  128. _fd = -1;
  129. }
  130. }
  131. /**
  132. * Sets the vibration strength. The first argument controls a low-frequency
  133. * motor, if present, and the latter controls a high-frequency motor.
  134. * The values are within the 0-1 range.
  135. */
  136. void EvdevInputDevice::
  137. do_set_vibration(double strong, double weak) {
  138. if (_fd == -1 || !_can_write) {
  139. return;
  140. }
  141. int strong_level = strong * 0xffff;
  142. int weak_level = weak * 0xffff;
  143. if (strong_level == _ff_strong && weak_level == _ff_weak) {
  144. // No change.
  145. return;
  146. }
  147. // Upload the new effect parameters. Do this even if we are about
  148. // to stop the effect, because some drivers don't respond to simply
  149. // stopping the effect.
  150. struct ff_effect effect;
  151. effect.type = FF_RUMBLE;
  152. effect.id = _ff_id;
  153. effect.direction = 0;
  154. effect.trigger.button = 0;
  155. effect.trigger.interval = 0;
  156. effect.replay.length = 0;
  157. effect.replay.delay = 0;
  158. effect.u.rumble.strong_magnitude = strong_level;
  159. effect.u.rumble.weak_magnitude = weak_level;
  160. if (ioctl(_fd, EVIOCSFF, &effect) < 0) {
  161. return;
  162. } else {
  163. _ff_id = effect.id;
  164. _ff_strong = strong_level;
  165. _ff_weak = weak_level;
  166. }
  167. if (!_ff_playing) {
  168. // Start the effect. We could pass 0 as value to stop the effect
  169. // when a level of 0 is requested, but my driver seems to ignore it.
  170. _ff_playing = true;
  171. struct input_event play;
  172. play.type = EV_FF;
  173. play.code = _ff_id;
  174. play.value = 1;
  175. if (write(_fd, &play, sizeof(play)) < 0) {
  176. device_cat.warning()
  177. << "Failed to write force-feedback event: " << strerror(errno) << "\n";
  178. }
  179. }
  180. }
  181. /**
  182. * Polls the input device for new activity, to ensure it contains the latest
  183. * events. This will only have any effect for some types of input devices;
  184. * others may be updated automatically, and this method will be a no-op.
  185. */
  186. void EvdevInputDevice::
  187. do_poll() {
  188. if (_fd != -1 && process_events()) {
  189. while (process_events()) {}
  190. // If we got events, we are obviously connected. Mark us so.
  191. if (!_is_connected) {
  192. _is_connected = true;
  193. if (_manager != nullptr) {
  194. _manager->add_device(this);
  195. }
  196. }
  197. }
  198. }
  199. /**
  200. * Reads basic properties from the device.
  201. */
  202. bool EvdevInputDevice::
  203. init_device() {
  204. using std::string;
  205. nassertr(_fd >= 0, false);
  206. LightMutexHolder holder(_lock);
  207. uint8_t evtypes[(EV_MAX + 8) >> 3] = {0};
  208. char name[128];
  209. if (ioctl(_fd, EVIOCGNAME(sizeof(name)), name) < 0 ||
  210. ioctl(_fd, EVIOCGBIT(0, sizeof(evtypes)), evtypes) < 0) {
  211. close(_fd);
  212. _fd = -1;
  213. _is_connected = false;
  214. device_cat.error() << "Opening raw input device: ioctl failed\n";
  215. return false;
  216. }
  217. _name.assign(name);
  218. //cerr << "##### Now initializing device " << name << "\n";
  219. struct input_id id;
  220. if (ioctl(_fd, EVIOCGID, &id) >= 0) {
  221. _vendor_id = id.vendor;
  222. _product_id = id.product;
  223. }
  224. bool all_values_zero = true;
  225. bool emulate_dpad = true;
  226. bool have_analog_triggers = false;
  227. bool has_keys = false;
  228. bool has_axes = false;
  229. uint8_t keys[(KEY_MAX + 8) >> 3] = {0};
  230. if (test_bit(EV_KEY, evtypes)) {
  231. // Check which buttons are on the device.
  232. ioctl(_fd, EVIOCGBIT(EV_KEY, sizeof(keys)), keys);
  233. has_keys = true;
  234. if (test_bit(KEY_A, keys) && test_bit(KEY_Z, keys)) {
  235. enable_feature(Feature::keyboard);
  236. }
  237. }
  238. int num_bits = 0;
  239. uint8_t axes[(ABS_MAX + 8) >> 3] = {0};
  240. if (test_bit(EV_ABS, evtypes)) {
  241. // Check which axes are on the device.
  242. num_bits = ioctl(_fd, EVIOCGBIT(EV_ABS, sizeof(axes)), axes) << 3;
  243. has_axes = true;
  244. }
  245. // Do we have a preset device mapping?
  246. int quirks = 0;
  247. const DeviceMapping *mapping = mapping_presets;
  248. while (mapping->vendor != 0) {
  249. if (_vendor_id == mapping->vendor && _product_id == mapping->product) {
  250. _device_class = mapping->device_class;
  251. quirks = mapping->quirks;
  252. break;
  253. }
  254. ++mapping;
  255. }
  256. // Try to detect which type of device we have here
  257. if (_device_class == DeviceClass::unknown) {
  258. int device_scores[(size_t)DeviceClass::spatial_mouse] = {0};
  259. // Test for specific keys
  260. if (test_bit(BTN_GAMEPAD, keys) && test_bit(ABS_X, axes) && test_bit(ABS_RX, axes)) {
  261. device_scores[(size_t)DeviceClass::gamepad] += 5;
  262. device_scores[(size_t)DeviceClass::steering_wheel] += 5;
  263. device_scores[(size_t)DeviceClass::flight_stick] += 5;
  264. }
  265. if (test_bit(ABS_WHEEL, axes) && test_bit(ABS_GAS, axes) && test_bit(ABS_BRAKE, axes)) {
  266. device_scores[(size_t)DeviceClass::steering_wheel] += 10;
  267. }
  268. if (test_bit(BTN_GEAR_DOWN, keys) && test_bit(BTN_GEAR_UP, keys)) {
  269. device_scores[(size_t)DeviceClass::steering_wheel] += 10;
  270. }
  271. if (test_bit(BTN_JOYSTICK, keys) && test_bit(ABS_X, axes)) {
  272. device_scores[(size_t)DeviceClass::flight_stick] += 10;
  273. }
  274. if (test_bit(BTN_MOUSE, keys) && test_bit(EV_REL, evtypes)) {
  275. device_scores[(size_t)DeviceClass::mouse] += 20;
  276. }
  277. uint8_t unknown_keys[] = {KEY_POWER};
  278. for (int i = 0; i < 1; i++) {
  279. if (test_bit(unknown_keys[i], keys)) {
  280. if (unknown_keys[i] == KEY_POWER) {
  281. }
  282. device_scores[(size_t)DeviceClass::unknown] += 20;
  283. }
  284. }
  285. if (_features & (unsigned int)Feature::keyboard) {
  286. device_scores[(size_t)DeviceClass::keyboard] += 20;
  287. }
  288. // Test for specific name tags
  289. string lowercase_name = _name;
  290. for(size_t x = 0; x < _name.length(); ++x) {
  291. lowercase_name[x] = tolower(lowercase_name[x]);
  292. }
  293. if (lowercase_name.find("gamepad") != string::npos) {
  294. device_scores[(size_t)DeviceClass::gamepad] += 10;
  295. }
  296. if (lowercase_name.find("wheel") != string::npos) {
  297. device_scores[(size_t)DeviceClass::steering_wheel] += 10;
  298. }
  299. if (lowercase_name.find("mouse") != string::npos || lowercase_name.find("touchpad") != string::npos) {
  300. device_scores[(size_t)DeviceClass::mouse] += 10;
  301. }
  302. if (lowercase_name.find("keyboard") != string::npos) {
  303. device_scores[(size_t)DeviceClass::keyboard] += 10;
  304. }
  305. // List of lowercase names that occur in unknown devices
  306. string unknown_names[] = {"video bus", "power button", "sleep button"};
  307. for(int i = 0; i < 3; i++) {
  308. if (lowercase_name.find(unknown_names[i]) != string::npos) {
  309. device_scores[(size_t)DeviceClass::unknown] += 20;
  310. }
  311. }
  312. // Check which device type got the most points
  313. int highest_score = 0;
  314. for (size_t i = 0; i < (size_t)DeviceClass::spatial_mouse; i++) {
  315. if (device_scores[i] > highest_score) {
  316. highest_score = device_scores[i];
  317. _device_class = (DeviceClass)i;
  318. }
  319. }
  320. //std::cerr << "Found highscore class " << _device_class << " with this score: " << highest_score << "\n";
  321. }
  322. if (has_keys) {
  323. // Also check whether the buttons are currently pressed.
  324. uint8_t states[(KEY_MAX + 8) >> 3] = {0};
  325. ioctl(_fd, EVIOCGKEY(sizeof(states)), states);
  326. for (int i = 0; i <= KEY_MAX; ++i) {
  327. if (test_bit(i, keys)) {
  328. ButtonState button;
  329. button.handle = map_button(i, _device_class);
  330. int button_index = (int)_buttons.size();
  331. if (button.handle == ButtonHandle::none()) {
  332. if (device_cat.is_debug()) {
  333. device_cat.debug() << "Unmapped /dev/input/event" << _index
  334. << " button " << button_index << ": 0x" << std::hex << i << std::dec << "\n";
  335. }
  336. }
  337. if (test_bit(i, states)) {
  338. button._state = S_down;
  339. all_values_zero = false;
  340. } else {
  341. button._state = S_up;
  342. }
  343. if (button.handle == GamepadButton::dpad_left()) {
  344. emulate_dpad = false;
  345. } else if (button.handle == GamepadButton::ltrigger()) {
  346. _ltrigger_code = i;
  347. } else if (button.handle == GamepadButton::rtrigger()) {
  348. _rtrigger_code = i;
  349. }
  350. _buttons.push_back(button);
  351. if ((size_t)i >= _button_indices.size()) {
  352. _button_indices.resize(i + 1, -1);
  353. }
  354. _button_indices[i] = button_index;
  355. }
  356. }
  357. }
  358. if (has_axes) {
  359. _axis_indices.resize(num_bits, -1);
  360. for (int i = 0; i < num_bits; ++i) {
  361. if (test_bit(i, axes)) {
  362. Axis axis = Axis::none;
  363. switch (i) {
  364. case ABS_X:
  365. if (_device_class == DeviceClass::gamepad) {
  366. axis = InputDevice::Axis::left_x;
  367. } else if (_device_class == DeviceClass::flight_stick) {
  368. axis = InputDevice::Axis::roll;
  369. } else {
  370. axis = InputDevice::Axis::x;
  371. }
  372. break;
  373. case ABS_Y:
  374. if (_device_class == DeviceClass::gamepad) {
  375. axis = InputDevice::Axis::left_y;
  376. } else if (_device_class == DeviceClass::flight_stick) {
  377. axis = InputDevice::Axis::pitch;
  378. } else {
  379. axis = InputDevice::Axis::y;
  380. }
  381. break;
  382. case ABS_Z:
  383. if (quirks & QB_rstick_from_z) {
  384. axis = InputDevice::Axis::right_x;
  385. } else if (_device_class == DeviceClass::gamepad) {
  386. axis = InputDevice::Axis::left_trigger;
  387. have_analog_triggers = true;
  388. } else if (_device_class == DeviceClass::spatial_mouse) {
  389. axis = InputDevice::Axis::z;
  390. } else {
  391. axis = InputDevice::Axis::throttle;
  392. }
  393. break;
  394. case ABS_RX:
  395. if (_device_class == DeviceClass::spatial_mouse) {
  396. axis = InputDevice::Axis::pitch;
  397. } else if ((quirks & QB_rstick_from_z) == 0) {
  398. axis = InputDevice::Axis::right_x;
  399. }
  400. break;
  401. case ABS_RY:
  402. if (_device_class == DeviceClass::spatial_mouse) {
  403. axis = InputDevice::Axis::roll;
  404. } else if ((quirks & QB_rstick_from_z) == 0) {
  405. axis = InputDevice::Axis::right_y;
  406. }
  407. break;
  408. case ABS_RZ:
  409. if (quirks & QB_rstick_from_z) {
  410. axis = InputDevice::Axis::right_y;
  411. } else if (_device_class == DeviceClass::gamepad) {
  412. axis = InputDevice::Axis::right_trigger;
  413. have_analog_triggers = true;
  414. } else {
  415. axis = InputDevice::Axis::yaw;
  416. }
  417. break;
  418. case ABS_THROTTLE:
  419. if (quirks & QB_rudder_from_throttle) {
  420. axis = InputDevice::Axis::rudder;
  421. } else {
  422. axis = InputDevice::Axis::throttle;
  423. }
  424. break;
  425. case ABS_RUDDER:
  426. axis = InputDevice::Axis::rudder;
  427. break;
  428. case ABS_WHEEL:
  429. axis = InputDevice::Axis::wheel;
  430. break;
  431. case ABS_GAS:
  432. if (_device_class == DeviceClass::gamepad) {
  433. axis = InputDevice::Axis::right_trigger;
  434. have_analog_triggers = true;
  435. } else {
  436. axis = InputDevice::Axis::accelerator;
  437. }
  438. break;
  439. case ABS_BRAKE:
  440. if (_device_class == DeviceClass::gamepad) {
  441. axis = InputDevice::Axis::left_trigger;
  442. have_analog_triggers = true;
  443. } else {
  444. axis = InputDevice::Axis::brake;
  445. }
  446. break;
  447. case ABS_HAT0X:
  448. if (emulate_dpad) {
  449. _dpad_x_axis = i;
  450. _dpad_left_button = (int)_buttons.size();
  451. if (_device_class == DeviceClass::gamepad) {
  452. _buttons.push_back(ButtonState(GamepadButton::dpad_left()));
  453. _buttons.push_back(ButtonState(GamepadButton::dpad_right()));
  454. } else {
  455. _buttons.push_back(ButtonState(GamepadButton::hat_left()));
  456. _buttons.push_back(ButtonState(GamepadButton::hat_right()));
  457. }
  458. }
  459. break;
  460. case ABS_HAT0Y:
  461. if (emulate_dpad) {
  462. _dpad_y_axis = i;
  463. _dpad_up_button = (int)_buttons.size();
  464. if (_device_class == DeviceClass::gamepad) {
  465. _buttons.push_back(ButtonState(GamepadButton::dpad_up()));
  466. _buttons.push_back(ButtonState(GamepadButton::dpad_down()));
  467. } else {
  468. _buttons.push_back(ButtonState(GamepadButton::hat_up()));
  469. _buttons.push_back(ButtonState(GamepadButton::hat_down()));
  470. }
  471. }
  472. break;
  473. }
  474. // Check the initial value and ranges.
  475. struct input_absinfo absinfo;
  476. if (ioctl(_fd, EVIOCGABS(i), &absinfo) >= 0) {
  477. int index;
  478. // We'd like to reverse the Y axis to match the XInput behavior.
  479. // Also reverse the yaw axis to match right-hand coordinate system.
  480. // Also T.Flight Hotas X throttle is reversed and can go backwards.
  481. if (axis == Axis::yaw || axis == Axis::rudder || axis == Axis::left_y || axis == Axis::right_y ||
  482. (axis == Axis::throttle && (quirks & QB_reversed_throttle) != 0) ||
  483. (_device_class == DeviceClass::spatial_mouse && (axis == Axis::y || axis == Axis::z || axis == Axis::roll))) {
  484. std::swap(absinfo.maximum, absinfo.minimum);
  485. }
  486. if (axis == Axis::throttle && (quirks & QB_centered_throttle) != 0) {
  487. index = add_axis(axis, absinfo.minimum, absinfo.maximum, true);
  488. } else {
  489. index = add_axis(axis, absinfo.minimum, absinfo.maximum);
  490. }
  491. axis_changed(index, absinfo.value);
  492. _axis_indices[i] = index;
  493. if (absinfo.value != 0) {
  494. all_values_zero = false;
  495. }
  496. }
  497. }
  498. }
  499. }
  500. if (test_bit(EV_REL, evtypes)) {
  501. enable_feature(Feature::pointer);
  502. add_pointer(PointerType::unknown, 0);
  503. }
  504. if (test_bit(EV_FF, evtypes)) {
  505. uint8_t effects[(FF_MAX + 8) >> 3] = {0};
  506. ioctl(_fd, EVIOCGBIT(EV_FF, sizeof(effects)), effects);
  507. if (test_bit(FF_RUMBLE, effects)) {
  508. if (_can_write) {
  509. enable_feature(Feature::vibration);
  510. } else {
  511. // Let the user know what he's missing out on.
  512. device_cat.warning()
  513. << "/dev/input/event" << _index << " is not writable, vibration "
  514. << "effects will be unavailable.\n";
  515. }
  516. }
  517. }
  518. if (_ltrigger_code >= 0 && _rtrigger_code >= 0 && !have_analog_triggers) {
  519. // Emulate analog triggers.
  520. _ltrigger_axis = (int)_axes.size();
  521. add_axis(Axis::left_trigger, 0, 1, false);
  522. add_axis(Axis::right_trigger, 0, 1, false);
  523. } else {
  524. _ltrigger_code = -1;
  525. _rtrigger_code = -1;
  526. }
  527. char path[64];
  528. char buffer[256];
  529. const char *parent = "";
  530. sprintf(path, "/sys/class/input/event%zd/device/device/../product", _index);
  531. FILE *f = fopen(path, "r");
  532. if (!f) {
  533. parent = "../";
  534. sprintf(path, "/sys/class/input/event%zd/device/device/%s../product", _index, parent);
  535. f = fopen(path, "r");
  536. }
  537. if (f) {
  538. if (fgets(buffer, sizeof(buffer), f) != nullptr) {
  539. buffer[strcspn(buffer, "\r\n")] = 0;
  540. if (buffer[0] != 0) {
  541. _name.assign(buffer);
  542. }
  543. }
  544. fclose(f);
  545. }
  546. sprintf(path, "/sys/class/input/event%zd/device/device/%s../manufacturer", _index, parent);
  547. f = fopen(path, "r");
  548. if (f) {
  549. if (fgets(buffer, sizeof(buffer), f) != nullptr) {
  550. buffer[strcspn(buffer, "\r\n")] = 0;
  551. _manufacturer.assign(buffer);
  552. }
  553. fclose(f);
  554. }
  555. sprintf(path, "/sys/class/input/event%zd/device/device/%s../serial", _index, parent);
  556. f = fopen(path, "r");
  557. if (f) {
  558. if (fgets(buffer, sizeof(buffer), f) != nullptr) {
  559. buffer[strcspn(buffer, "\r\n")] = 0;
  560. _serial_number.assign(buffer);
  561. }
  562. fclose(f);
  563. }
  564. // Special-case fix for Xbox 360 Wireless Receiver: the Linux kernel
  565. // driver always reports 4 connected gamepads, regardless of the number
  566. // of gamepads actually present. This hack partially remedies this.
  567. if (all_values_zero && (quirks & QB_connect_if_nonzero) != 0) {
  568. _is_connected = false;
  569. } else {
  570. _is_connected = true;
  571. }
  572. return true;
  573. }
  574. /**
  575. * Reads a number of events from the device. Returns true if events were read,
  576. * meaning this function should keep being called until it returns false.
  577. */
  578. bool EvdevInputDevice::
  579. process_events() {
  580. // Read 8 events at a time.
  581. struct input_event events[8];
  582. int n_read = read(_fd, events, sizeof(events));
  583. if (n_read < 0) {
  584. if (errno == EAGAIN || errno == EWOULDBLOCK) {
  585. // No data available for now.
  586. } else if (errno == ENODEV || errno == EINVAL) {
  587. // The device ceased to exist, so we better close it. No need
  588. // to worry about removing it from the InputDeviceManager, as it
  589. // will get an inotify event sooner or later about this.
  590. close(_fd);
  591. _fd = -1;
  592. //_is_connected = false;
  593. errno = 0;
  594. } else {
  595. device_cat.error() << "read: " << strerror(errno) << "\n";
  596. }
  597. return false;
  598. }
  599. if (n_read == 0) {
  600. return false;
  601. }
  602. n_read /= sizeof(struct input_event);
  603. int rel_x = 0;
  604. int rel_y = 0;
  605. double time = ClockObject::get_global_clock()->get_frame_time();
  606. int index;
  607. // It seems that some devices send a single EV_SYN event when being
  608. // unplugged. Boo. Ignore it.
  609. if (n_read == 1 && events[0].code == EV_SYN) {
  610. return false;
  611. }
  612. for (int i = 0; i < n_read; ++i) {
  613. int code = events[i].code;
  614. switch (events[i].type) {
  615. case EV_SYN:
  616. break;
  617. case EV_REL:
  618. if (code == REL_X) rel_x += events[i].value;
  619. if (code == REL_Y) rel_y += events[i].value;
  620. break;
  621. case EV_ABS:
  622. if (code == _dpad_x_axis) {
  623. button_changed(_dpad_left_button, events[i].value < 0);
  624. button_changed(_dpad_left_button+1, events[i].value > 0);
  625. } else if (code == _dpad_y_axis) {
  626. button_changed(_dpad_up_button, events[i].value < 0);
  627. button_changed(_dpad_up_button+1, events[i].value > 0);
  628. }
  629. nassertd(code >= 0 && (size_t)code < _axis_indices.size()) break;
  630. index = _axis_indices[code];
  631. if (index >= 0) {
  632. axis_changed(index, events[i].value);
  633. }
  634. break;
  635. case EV_KEY:
  636. nassertd(code >= 0 && (size_t)code < _button_indices.size()) break;
  637. index = _button_indices[code];
  638. if (index >= 0) {
  639. button_changed(index, events[i].value != 0);
  640. }
  641. if (code == _ltrigger_code) {
  642. axis_changed(_ltrigger_axis, events[i].value);
  643. } else if (code == _rtrigger_code) {
  644. axis_changed(_ltrigger_axis + 1, events[i].value);
  645. }
  646. break;
  647. default:
  648. //cerr << "event " << events[i].type << " - " << events[i].code << " - " << events[i].value << "\n";
  649. break;
  650. }
  651. }
  652. if (rel_x != 0 || rel_y != 0) {
  653. pointer_moved(0, rel_x, rel_y, time);
  654. }
  655. return true;
  656. }
  657. /**
  658. * Static function to map an evdev code to a ButtonHandle.
  659. */
  660. ButtonHandle EvdevInputDevice::
  661. map_button(int code, DeviceClass device_class) {
  662. if (code >= 0 && code < 0x80) {
  663. // See linux/input.h for the source of this mapping.
  664. static const ButtonHandle keyboard_map[] = {
  665. ButtonHandle::none(),
  666. KeyboardButton::escape(),
  667. KeyboardButton::ascii_key('1'),
  668. KeyboardButton::ascii_key('2'),
  669. KeyboardButton::ascii_key('3'),
  670. KeyboardButton::ascii_key('4'),
  671. KeyboardButton::ascii_key('5'),
  672. KeyboardButton::ascii_key('6'),
  673. KeyboardButton::ascii_key('7'),
  674. KeyboardButton::ascii_key('8'),
  675. KeyboardButton::ascii_key('9'),
  676. KeyboardButton::ascii_key('0'),
  677. KeyboardButton::ascii_key('-'),
  678. KeyboardButton::ascii_key('='),
  679. KeyboardButton::backspace(),
  680. KeyboardButton::tab(),
  681. KeyboardButton::ascii_key('q'),
  682. KeyboardButton::ascii_key('w'),
  683. KeyboardButton::ascii_key('e'),
  684. KeyboardButton::ascii_key('r'),
  685. KeyboardButton::ascii_key('t'),
  686. KeyboardButton::ascii_key('y'),
  687. KeyboardButton::ascii_key('u'),
  688. KeyboardButton::ascii_key('i'),
  689. KeyboardButton::ascii_key('o'),
  690. KeyboardButton::ascii_key('p'),
  691. KeyboardButton::ascii_key('['),
  692. KeyboardButton::ascii_key(']'),
  693. KeyboardButton::enter(),
  694. KeyboardButton::lcontrol(),
  695. KeyboardButton::ascii_key('a'),
  696. KeyboardButton::ascii_key('s'),
  697. KeyboardButton::ascii_key('d'),
  698. KeyboardButton::ascii_key('f'),
  699. KeyboardButton::ascii_key('g'),
  700. KeyboardButton::ascii_key('h'),
  701. KeyboardButton::ascii_key('j'),
  702. KeyboardButton::ascii_key('k'),
  703. KeyboardButton::ascii_key('l'),
  704. KeyboardButton::ascii_key(';'),
  705. KeyboardButton::ascii_key('\''),
  706. KeyboardButton::ascii_key('`'),
  707. KeyboardButton::lshift(),
  708. KeyboardButton::ascii_key('\\'),
  709. KeyboardButton::ascii_key('z'),
  710. KeyboardButton::ascii_key('x'),
  711. KeyboardButton::ascii_key('c'),
  712. KeyboardButton::ascii_key('v'),
  713. KeyboardButton::ascii_key('b'),
  714. KeyboardButton::ascii_key('n'),
  715. KeyboardButton::ascii_key('m'),
  716. KeyboardButton::ascii_key(','),
  717. KeyboardButton::ascii_key('.'),
  718. KeyboardButton::ascii_key('/'),
  719. KeyboardButton::rshift(),
  720. KeyboardButton::ascii_key('*'),
  721. KeyboardButton::lalt(),
  722. KeyboardButton::space(),
  723. KeyboardButton::caps_lock(),
  724. KeyboardButton::f1(),
  725. KeyboardButton::f2(),
  726. KeyboardButton::f3(),
  727. KeyboardButton::f4(),
  728. KeyboardButton::f5(),
  729. KeyboardButton::f6(),
  730. KeyboardButton::f7(),
  731. KeyboardButton::f8(),
  732. KeyboardButton::f9(),
  733. KeyboardButton::f10(),
  734. KeyboardButton::num_lock(),
  735. KeyboardButton::scroll_lock(),
  736. KeyboardButton::ascii_key('7'),
  737. KeyboardButton::ascii_key('8'),
  738. KeyboardButton::ascii_key('9'),
  739. KeyboardButton::ascii_key('-'),
  740. KeyboardButton::ascii_key('4'),
  741. KeyboardButton::ascii_key('5'),
  742. KeyboardButton::ascii_key('6'),
  743. KeyboardButton::ascii_key('+'),
  744. KeyboardButton::ascii_key('1'),
  745. KeyboardButton::ascii_key('2'),
  746. KeyboardButton::ascii_key('3'),
  747. KeyboardButton::ascii_key('0'),
  748. KeyboardButton::ascii_key('.'),
  749. ButtonHandle::none(),
  750. ButtonHandle::none(),
  751. ButtonHandle::none(),
  752. KeyboardButton::f11(),
  753. KeyboardButton::f12(),
  754. ButtonHandle::none(),
  755. ButtonHandle::none(),
  756. ButtonHandle::none(),
  757. ButtonHandle::none(),
  758. ButtonHandle::none(),
  759. ButtonHandle::none(),
  760. ButtonHandle::none(),
  761. KeyboardButton::enter(),
  762. KeyboardButton::rcontrol(),
  763. KeyboardButton::ascii_key('/'),
  764. KeyboardButton::print_screen(),
  765. KeyboardButton::ralt(),
  766. ButtonHandle::none(),
  767. KeyboardButton::home(),
  768. KeyboardButton::up(),
  769. KeyboardButton::page_up(),
  770. KeyboardButton::left(),
  771. KeyboardButton::right(),
  772. KeyboardButton::end(),
  773. KeyboardButton::down(),
  774. KeyboardButton::page_down(),
  775. KeyboardButton::insert(),
  776. KeyboardButton::del(),
  777. ButtonHandle::none(),
  778. ButtonHandle::none(),
  779. ButtonHandle::none(),
  780. ButtonHandle::none(),
  781. ButtonHandle::none(),
  782. ButtonHandle::none(),
  783. ButtonHandle::none(),
  784. KeyboardButton::pause(),
  785. ButtonHandle::none(),
  786. ButtonHandle::none(),
  787. ButtonHandle::none(),
  788. ButtonHandle::none(),
  789. ButtonHandle::none(),
  790. KeyboardButton::lmeta(),
  791. KeyboardButton::rmeta(),
  792. KeyboardButton::menu(),
  793. };
  794. return keyboard_map[code];
  795. } else if (code == KEY_BACK) {
  796. // Used by NVIDIA Shield Controller
  797. return GamepadButton::back();
  798. } else if (code == KEY_SEARCH) {
  799. // Used by NVIDIA Shield Controller
  800. return GamepadButton::guide();
  801. } else if (code < 0x100) {
  802. return ButtonHandle::none();
  803. } else if ((code & 0xfff0) == BTN_MOUSE) {
  804. // The number for these is reversed in Panda.
  805. if (code == BTN_RIGHT) {
  806. return MouseButton::three();
  807. } else if (code == BTN_MIDDLE) {
  808. return MouseButton::two();
  809. } else {
  810. return MouseButton::button(code - BTN_MOUSE);
  811. }
  812. } else if ((code & 0xfff0) == BTN_JOYSTICK) {
  813. if (device_class == DeviceClass::gamepad) {
  814. // Based on "Jess Tech Colour Rumble Pad"
  815. static const ButtonHandle mapping[] = {
  816. GamepadButton::face_x(),
  817. GamepadButton::face_y(),
  818. GamepadButton::face_a(),
  819. GamepadButton::face_b(),
  820. GamepadButton::lshoulder(),
  821. GamepadButton::ltrigger(),
  822. GamepadButton::rshoulder(),
  823. GamepadButton::rtrigger(),
  824. GamepadButton::back(),
  825. GamepadButton::start(),
  826. GamepadButton::lstick(),
  827. GamepadButton::rstick(),
  828. };
  829. if ((code & 0xf) < 12) {
  830. return mapping[code & 0xf];
  831. }
  832. } else {
  833. return GamepadButton::joystick(code & 0xf);
  834. }
  835. }
  836. switch (code) {
  837. case BTN_A:
  838. return GamepadButton::face_a();
  839. case BTN_B:
  840. return GamepadButton::face_b();
  841. case BTN_C:
  842. return GamepadButton::face_c();
  843. case BTN_X:
  844. return GamepadButton::face_x();
  845. case BTN_Y:
  846. return GamepadButton::face_y();
  847. case BTN_Z:
  848. return GamepadButton::face_z();
  849. case BTN_TL:
  850. return GamepadButton::lshoulder();
  851. case BTN_TR:
  852. return GamepadButton::rshoulder();
  853. case BTN_TL2:
  854. return GamepadButton::ltrigger();
  855. case BTN_TR2:
  856. return GamepadButton::rtrigger();
  857. case BTN_1:
  858. return GamepadButton::face_1();
  859. case BTN_2:
  860. return GamepadButton::face_2();
  861. case BTN_SELECT:
  862. case KEY_PREVIOUS:
  863. return GamepadButton::back();
  864. case BTN_START:
  865. case KEY_NEXT:
  866. return GamepadButton::start();
  867. case BTN_MODE:
  868. return GamepadButton::guide();
  869. case BTN_THUMBL:
  870. return GamepadButton::lstick();
  871. case BTN_THUMBR:
  872. return GamepadButton::rstick();
  873. case BTN_DPAD_LEFT:
  874. case BTN_TRIGGER_HAPPY1:
  875. return GamepadButton::dpad_left();
  876. case BTN_DPAD_RIGHT:
  877. case BTN_TRIGGER_HAPPY2:
  878. return GamepadButton::dpad_right();
  879. case BTN_DPAD_UP:
  880. case BTN_TRIGGER_HAPPY3:
  881. return GamepadButton::dpad_up();
  882. case BTN_DPAD_DOWN:
  883. case BTN_TRIGGER_HAPPY4:
  884. return GamepadButton::dpad_down();
  885. default:
  886. return ButtonHandle::none();
  887. }
  888. }
  889. #endif