evdev.cpp 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877
  1. // Copyright 2015 Dolphin Emulator Project
  2. // SPDX-License-Identifier: GPL-2.0-or-later
  3. #include "InputCommon/ControllerInterface/evdev/evdev.h"
  4. #include <algorithm>
  5. #include <cstring>
  6. #include <map>
  7. #include <memory>
  8. #include <string>
  9. #include <fcntl.h>
  10. #include <libudev.h>
  11. #include <sys/eventfd.h>
  12. #include <unistd.h>
  13. #include "Common/Assert.h"
  14. #include "Common/Flag.h"
  15. #include "Common/Logging/Log.h"
  16. #include "Common/MathUtil.h"
  17. #include "Common/ScopeGuard.h"
  18. #include "Common/StringUtil.h"
  19. #include "Common/Thread.h"
  20. #include "Common/WorkQueueThread.h"
  21. #include "InputCommon/ControllerInterface/ControllerInterface.h"
  22. namespace ciface::evdev
  23. {
  24. class InputBackend final : public ciface::InputBackend
  25. {
  26. public:
  27. InputBackend(ControllerInterface* controller_interface);
  28. ~InputBackend();
  29. void PopulateDevices() override;
  30. void RemoveDevnodeObject(const std::string&);
  31. // Linux has the strange behavior that closing file descriptors of event devices can be
  32. // surprisingly slow, in the range of 20-70 milliseconds. For modern systems that have maybe 30
  33. // event devices this can quickly add up, leading to visibly slow startup. So we close FDs on a
  34. // separate thread *shrug*
  35. void CloseDescriptor(int fd) { m_cleanup_thread.Push(fd); }
  36. private:
  37. std::shared_ptr<evdevDevice>
  38. FindDeviceWithUniqueIDAndPhysicalLocation(const char* unique_id, const char* physical_location);
  39. void AddDeviceNode(const char* devnode);
  40. void StartHotplugThread();
  41. void StopHotplugThread();
  42. void HotplugThreadFunc();
  43. std::thread m_hotplug_thread;
  44. Common::Flag m_hotplug_thread_running;
  45. int m_wakeup_eventfd;
  46. // There is no easy way to get the device name from only a dev node
  47. // during a device removed event, since libevdev can't work on removed devices;
  48. // sysfs is not stable, so this is probably the easiest way to get a name for a node.
  49. // This can, and will be modified by different thread, possibly concurrently,
  50. // as devices can be destroyed by any thread at any time. As of now it's protected
  51. // by ControllerInterface::m_devices_population_mutex.
  52. std::map<std::string, std::weak_ptr<evdevDevice>> m_devnode_objects;
  53. Common::WorkQueueThread<int> m_cleanup_thread;
  54. };
  55. std::unique_ptr<ciface::InputBackend> CreateInputBackend(ControllerInterface* controller_interface)
  56. {
  57. return std::make_unique<InputBackend>(controller_interface);
  58. }
  59. class Input : public Core::Device::Input
  60. {
  61. public:
  62. Input(u16 code, libevdev* dev) : m_code(code), m_dev(dev) {}
  63. protected:
  64. const u16 m_code;
  65. libevdev* const m_dev;
  66. };
  67. class Button : public Input
  68. {
  69. public:
  70. Button(u8 index, u16 code, libevdev* dev) : Input(code, dev), m_index(index) {}
  71. ControlState GetState() const final override
  72. {
  73. int value = 0;
  74. libevdev_fetch_event_value(m_dev, EV_KEY, m_code, &value);
  75. return value;
  76. }
  77. protected:
  78. std::optional<std::string> GetEventCodeName() const
  79. {
  80. if (const char* code_name = libevdev_event_code_get_name(EV_KEY, m_code))
  81. {
  82. const auto name = StripWhitespace(code_name);
  83. for (auto remove_prefix : {"BTN_", "KEY_"})
  84. {
  85. if (name.starts_with(remove_prefix))
  86. return std::string(name.substr(std::strlen(remove_prefix)));
  87. }
  88. return std::string(name);
  89. }
  90. else
  91. {
  92. return std::nullopt;
  93. }
  94. }
  95. std::string GetIndexedName() const { return "Button " + std::to_string(m_index); }
  96. const u8 m_index;
  97. };
  98. class NumberedButton final : public Button
  99. {
  100. public:
  101. using Button::Button;
  102. std::string GetName() const override { return GetIndexedName(); }
  103. };
  104. class NamedButton final : public Button
  105. {
  106. public:
  107. using Button::Button;
  108. bool IsMatchingName(std::string_view name) const final override
  109. {
  110. // Match either the "START" naming provided by evdev or the "Button 0"-like naming.
  111. return name == GetEventCodeName() || name == GetIndexedName();
  112. }
  113. std::string GetName() const override { return GetEventCodeName().value_or(GetIndexedName()); }
  114. };
  115. class NamedButtonWithNoBackwardsCompat final : public Button
  116. {
  117. public:
  118. using Button::Button;
  119. std::string GetName() const override { return GetEventCodeName().value_or(GetIndexedName()); }
  120. };
  121. class AnalogInput : public Input
  122. {
  123. public:
  124. using Input::Input;
  125. ControlState GetState() const final override
  126. {
  127. int value = 0;
  128. libevdev_fetch_event_value(m_dev, EV_ABS, m_code, &value);
  129. return (value - m_base) / m_range;
  130. }
  131. protected:
  132. ControlState m_range;
  133. int m_base;
  134. };
  135. class Axis : public AnalogInput
  136. {
  137. public:
  138. Axis(u8 index, u16 code, bool upper, libevdev* dev) : AnalogInput(code, dev), m_index(index)
  139. {
  140. const int min = libevdev_get_abs_minimum(m_dev, m_code);
  141. const int max = libevdev_get_abs_maximum(m_dev, m_code);
  142. m_base = (max + min) / 2;
  143. m_range = (upper ? max : min) - m_base;
  144. }
  145. std::string GetName() const override { return GetIndexedName(); }
  146. protected:
  147. std::string GetIndexedName() const
  148. {
  149. return "Axis " + std::to_string(m_index) + (m_range < 0 ? '-' : '+');
  150. }
  151. private:
  152. const u8 m_index;
  153. };
  154. class MotionDataInput final : public AnalogInput
  155. {
  156. public:
  157. MotionDataInput(u16 code, ControlState resolution_scale, libevdev* dev) : AnalogInput(code, dev)
  158. {
  159. auto* const info = libevdev_get_abs_info(m_dev, m_code);
  160. // The average of the minimum and maximum value. (neutral value)
  161. m_base = (info->maximum + info->minimum) / 2;
  162. m_range = info->resolution / resolution_scale;
  163. }
  164. std::string GetName() const override
  165. {
  166. // Unfortunately there doesn't seem to be a "standard" orientation
  167. // so we can't use "Accel Up"-like names.
  168. constexpr std::array<const char*, 6> motion_data_names = {{
  169. "Accel X",
  170. "Accel Y",
  171. "Accel Z",
  172. "Gyro X",
  173. "Gyro Y",
  174. "Gyro Z",
  175. }};
  176. // Our name array relies on sane axis codes from 0 to 5.
  177. static_assert(ABS_X == 0, "evdev axis value sanity check");
  178. static_assert(ABS_RX == 3, "evdev axis value sanity check");
  179. return std::string(motion_data_names[m_code]) + (m_range < 0 ? '-' : '+');
  180. }
  181. bool IsDetectable() const override { return false; }
  182. };
  183. class CursorInput final : public Axis
  184. {
  185. public:
  186. using Axis::Axis;
  187. std::string GetName() const final override
  188. {
  189. // "Cursor X-" naming.
  190. return std::string("Cursor ") + char('X' + m_code) + (m_range < 0 ? '-' : '+');
  191. }
  192. bool IsDetectable() const override { return false; }
  193. };
  194. std::shared_ptr<evdevDevice>
  195. InputBackend::FindDeviceWithUniqueIDAndPhysicalLocation(const char* unique_id,
  196. const char* physical_location)
  197. {
  198. if (!unique_id || !physical_location)
  199. return nullptr;
  200. for (auto& [node, dev] : m_devnode_objects)
  201. {
  202. if (const auto device = dev.lock())
  203. {
  204. const auto* dev_uniq = device->GetUniqueID();
  205. const auto* dev_phys = device->GetPhysicalLocation();
  206. if (dev_uniq && dev_phys && std::strcmp(dev_uniq, unique_id) == 0 &&
  207. std::strcmp(dev_phys, physical_location) == 0)
  208. {
  209. return device;
  210. }
  211. }
  212. }
  213. return nullptr;
  214. }
  215. void InputBackend::AddDeviceNode(const char* devnode)
  216. {
  217. // Unfortunately udev gives us no way to filter out the non event device interfaces.
  218. // So we open it and see if it works with evdev ioctls or not.
  219. // The device file will be read on one of the main threads, so we open in non-blocking mode.
  220. const int fd = open(devnode, O_RDWR | O_NONBLOCK);
  221. if (fd == -1)
  222. {
  223. return;
  224. }
  225. libevdev* dev = nullptr;
  226. if (libevdev_new_from_fd(fd, &dev) != 0)
  227. {
  228. // This usually fails because the device node isn't an evdev device, such as /dev/input/js0
  229. CloseDescriptor(fd);
  230. return;
  231. }
  232. const auto uniq = libevdev_get_uniq(dev);
  233. const auto phys = libevdev_get_phys(dev);
  234. auto evdev_device = FindDeviceWithUniqueIDAndPhysicalLocation(uniq, phys);
  235. if (evdev_device)
  236. {
  237. NOTICE_LOG_FMT(CONTROLLERINTERFACE,
  238. "evdev combining devices with unique id: {}, physical location: {}", uniq, phys);
  239. evdev_device->AddNode(devnode, fd, dev);
  240. // Remove and re-add device as naming and inputs may have changed.
  241. // This will also give it the correct index and invoke device change callbacks.
  242. // Make sure to force the device removal immediately (as they are shared ptrs and
  243. // they could be kept alive, preventing us from re-creating the device)
  244. GetControllerInterface().RemoveDevice(
  245. [&evdev_device](const auto* device) {
  246. return static_cast<const evdevDevice*>(device) == evdev_device.get();
  247. },
  248. true);
  249. GetControllerInterface().AddDevice(evdev_device);
  250. }
  251. else
  252. {
  253. evdev_device = std::make_shared<evdevDevice>(this);
  254. const bool was_interesting = evdev_device->AddNode(devnode, fd, dev);
  255. if (was_interesting)
  256. GetControllerInterface().AddDevice(evdev_device);
  257. }
  258. // If the devices failed to be added to ControllerInterface, it will be added here but then
  259. // immediately removed in its destructor due to the shared ptr not having any references left
  260. m_devnode_objects.emplace(devnode, std::move(evdev_device));
  261. }
  262. void InputBackend::HotplugThreadFunc()
  263. {
  264. Common::SetCurrentThreadName("evdev Hotplug Thread");
  265. NOTICE_LOG_FMT(CONTROLLERINTERFACE, "evdev hotplug thread started");
  266. udev* const udev = udev_new();
  267. Common::ScopeGuard udev_guard([udev] { udev_unref(udev); });
  268. ASSERT_MSG(CONTROLLERINTERFACE, udev != nullptr, "Couldn't initialize libudev.");
  269. // Set up monitoring
  270. udev_monitor* const monitor = udev_monitor_new_from_netlink(udev, "udev");
  271. Common::ScopeGuard monitor_guard([monitor] { udev_monitor_unref(monitor); });
  272. udev_monitor_filter_add_match_subsystem_devtype(monitor, "input", nullptr);
  273. udev_monitor_enable_receiving(monitor);
  274. const int monitor_fd = udev_monitor_get_fd(monitor);
  275. while (m_hotplug_thread_running.IsSet())
  276. {
  277. fd_set fds;
  278. FD_ZERO(&fds);
  279. FD_SET(monitor_fd, &fds);
  280. FD_SET(m_wakeup_eventfd, &fds);
  281. const int ret =
  282. select(std::max(monitor_fd, m_wakeup_eventfd) + 1, &fds, nullptr, nullptr, nullptr);
  283. if (ret < 1 || !FD_ISSET(monitor_fd, &fds))
  284. continue;
  285. udev_device* const dev = udev_monitor_receive_device(monitor);
  286. Common::ScopeGuard dev_guard([dev] { udev_device_unref(dev); });
  287. const char* const action = udev_device_get_action(dev);
  288. const char* const devnode = udev_device_get_devnode(dev);
  289. if (!devnode)
  290. continue;
  291. // Use GetControllerInterface().PlatformPopulateDevices() to protect access around
  292. // m_devnode_objects. Note that even if we get these events at the same time as a
  293. // a PopulateDevices() request (e.g. on start up, we might get all the add events
  294. // for connected devices), this won't ever cause duplicate devices as AddDeviceNode()
  295. // automatically removes the old one if it already existed
  296. if (strcmp(action, "remove") == 0)
  297. {
  298. GetControllerInterface().PlatformPopulateDevices([&devnode, this] {
  299. std::shared_ptr<evdevDevice> ptr;
  300. const auto it = m_devnode_objects.find(devnode);
  301. if (it != m_devnode_objects.end())
  302. ptr = it->second.lock();
  303. // If we don't recognize this device, ptr will be null and no device will be removed.
  304. GetControllerInterface().RemoveDevice([&ptr](const auto* device) {
  305. return static_cast<const evdevDevice*>(device) == ptr.get();
  306. });
  307. });
  308. }
  309. else if (strcmp(action, "add") == 0)
  310. {
  311. GetControllerInterface().PlatformPopulateDevices(
  312. [&devnode, this] { AddDeviceNode(devnode); });
  313. }
  314. }
  315. NOTICE_LOG_FMT(CONTROLLERINTERFACE, "evdev hotplug thread stopped");
  316. }
  317. void InputBackend::StartHotplugThread()
  318. {
  319. // Mark the thread as running.
  320. if (!m_hotplug_thread_running.TestAndSet())
  321. {
  322. // It was already running.
  323. return;
  324. }
  325. m_wakeup_eventfd = eventfd(0, 0);
  326. ASSERT_MSG(CONTROLLERINTERFACE, m_wakeup_eventfd != -1, "Couldn't create eventfd.");
  327. m_hotplug_thread = std::thread(&InputBackend::HotplugThreadFunc, this);
  328. }
  329. void InputBackend::StopHotplugThread()
  330. {
  331. // Tell the hotplug thread to stop.
  332. if (!m_hotplug_thread_running.TestAndClear())
  333. {
  334. // It wasn't running, we're done.
  335. return;
  336. }
  337. // Write something to efd so that select() stops blocking.
  338. const uint64_t value = 1;
  339. static_cast<void>(!write(m_wakeup_eventfd, &value, sizeof(uint64_t)));
  340. m_hotplug_thread.join();
  341. close(m_wakeup_eventfd);
  342. }
  343. InputBackend::InputBackend(ControllerInterface* controller_interface)
  344. : ciface::InputBackend(controller_interface), m_cleanup_thread("evdev cleanup", close)
  345. {
  346. StartHotplugThread();
  347. }
  348. // Only call this when ControllerInterface::m_devices_population_mutex is locked
  349. void InputBackend::PopulateDevices()
  350. {
  351. // Don't run if we are not initialized
  352. if (!m_hotplug_thread_running.IsSet())
  353. {
  354. return;
  355. }
  356. // We use udev to iterate over all /dev/input/event* devices.
  357. // Note: the Linux kernel is currently limited to just 32 event devices. If
  358. // this ever changes, hopefully udev will take care of this.
  359. udev* const udev = udev_new();
  360. ASSERT_MSG(CONTROLLERINTERFACE, udev != nullptr, "Couldn't initialize libudev.");
  361. // List all input devices
  362. udev_enumerate* const enumerate = udev_enumerate_new(udev);
  363. udev_enumerate_add_match_subsystem(enumerate, "input");
  364. udev_enumerate_scan_devices(enumerate);
  365. udev_list_entry* const devices = udev_enumerate_get_list_entry(enumerate);
  366. // Iterate over all input devices
  367. udev_list_entry* dev_list_entry;
  368. udev_list_entry_foreach(dev_list_entry, devices)
  369. {
  370. const char* path = udev_list_entry_get_name(dev_list_entry);
  371. udev_device* dev = udev_device_new_from_syspath(udev, path);
  372. if (const char* devnode = udev_device_get_devnode(dev))
  373. AddDeviceNode(devnode);
  374. udev_device_unref(dev);
  375. }
  376. udev_enumerate_unref(enumerate);
  377. udev_unref(udev);
  378. }
  379. InputBackend::~InputBackend()
  380. {
  381. StopHotplugThread();
  382. }
  383. bool evdevDevice::AddNode(std::string devnode, int fd, libevdev* dev)
  384. {
  385. m_nodes.emplace_back(Node{std::move(devnode), fd, dev});
  386. // Take on the alphabetically first name.
  387. const auto potential_new_name = StripWhitespace(libevdev_get_name(dev));
  388. if (m_name.empty() || potential_new_name < m_name)
  389. m_name = potential_new_name;
  390. const bool is_motion_device = libevdev_has_property(dev, INPUT_PROP_ACCELEROMETER);
  391. const bool is_pointing_device = libevdev_has_property(dev, INPUT_PROP_BUTTONPAD);
  392. // If a device has BTN_JOYSTICK it probably uses event codes counting up from 0x120
  393. // which have very useless and wrong names.
  394. const bool has_btn_joystick = libevdev_has_event_code(dev, EV_KEY, BTN_JOYSTICK);
  395. const bool has_sensible_button_names = !has_btn_joystick;
  396. // Buttons (and keyboard keys)
  397. int num_buttons = 0;
  398. for (int key = 0; key != KEY_CNT; ++key)
  399. {
  400. if (libevdev_has_event_code(dev, EV_KEY, key))
  401. {
  402. if (is_pointing_device || is_motion_device)
  403. {
  404. // This node will probably be combined with another with regular buttons.
  405. // We don't want to match "Button 0" names here as it will name clash.
  406. AddInput(new NamedButtonWithNoBackwardsCompat(num_buttons, key, dev));
  407. }
  408. else if (has_sensible_button_names)
  409. {
  410. AddInput(new NamedButton(num_buttons, key, dev));
  411. }
  412. else
  413. {
  414. AddInput(new NumberedButton(num_buttons, key, dev));
  415. }
  416. ++num_buttons;
  417. }
  418. }
  419. int num_axis = 0;
  420. if (is_motion_device)
  421. {
  422. // If INPUT_PROP_ACCELEROMETER is set then X,Y,Z,RX,RY,RZ contain motion data.
  423. auto add_motion_inputs = [&num_axis, dev, this](int first_code, double scale) {
  424. for (int i = 0; i != 3; ++i)
  425. {
  426. const int code = first_code + i;
  427. if (libevdev_has_event_code(dev, EV_ABS, code))
  428. {
  429. AddInput(new MotionDataInput(code, scale * -1, dev));
  430. AddInput(new MotionDataInput(code, scale, dev));
  431. ++num_axis;
  432. }
  433. }
  434. };
  435. // evdev resolution is specified in "g"s and deg/s.
  436. // Convert these to m/s/s and rad/s.
  437. constexpr ControlState accel_scale = MathUtil::GRAVITY_ACCELERATION;
  438. constexpr ControlState gyro_scale = MathUtil::TAU / 360;
  439. add_motion_inputs(ABS_X, accel_scale);
  440. add_motion_inputs(ABS_RX, gyro_scale);
  441. return true;
  442. }
  443. if (is_pointing_device)
  444. {
  445. auto add_cursor_input = [&num_axis, dev, this](int code) {
  446. if (libevdev_has_event_code(dev, EV_ABS, code))
  447. {
  448. AddInput(new CursorInput(num_axis, code, false, dev));
  449. AddInput(new CursorInput(num_axis, code, true, dev));
  450. ++num_axis;
  451. }
  452. };
  453. add_cursor_input(ABS_X);
  454. add_cursor_input(ABS_Y);
  455. return true;
  456. }
  457. // Axes beyond ABS_MISC have strange behavior (for multi-touch) which we do not handle.
  458. const int abs_axis_code_count = ABS_MISC;
  459. // Absolute axis (thumbsticks)
  460. for (int axis = 0; axis != abs_axis_code_count; ++axis)
  461. {
  462. if (libevdev_has_event_code(dev, EV_ABS, axis))
  463. {
  464. AddFullAnalogSurfaceInputs(new Axis(num_axis, axis, false, dev),
  465. new Axis(num_axis, axis, true, dev));
  466. ++num_axis;
  467. }
  468. }
  469. // Disable autocenter
  470. if (libevdev_has_event_code(dev, EV_FF, FF_AUTOCENTER))
  471. {
  472. input_event ie = {};
  473. ie.type = EV_FF;
  474. ie.code = FF_AUTOCENTER;
  475. ie.value = 0;
  476. static_cast<void>(!write(fd, &ie, sizeof(ie)));
  477. }
  478. // Constant FF effect
  479. if (libevdev_has_event_code(dev, EV_FF, FF_CONSTANT))
  480. {
  481. AddOutput(new ConstantEffect(fd));
  482. }
  483. // Periodic FF effects
  484. if (libevdev_has_event_code(dev, EV_FF, FF_PERIODIC))
  485. {
  486. for (auto wave : {FF_SINE, FF_SQUARE, FF_TRIANGLE, FF_SAW_UP, FF_SAW_DOWN})
  487. {
  488. if (libevdev_has_event_code(dev, EV_FF, wave))
  489. AddOutput(new PeriodicEffect(fd, wave));
  490. }
  491. }
  492. // Rumble (i.e. Left/Right) (i.e. Strong/Weak) effect
  493. if (libevdev_has_event_code(dev, EV_FF, FF_RUMBLE))
  494. {
  495. AddOutput(new RumbleEffect(fd, RumbleEffect::Motor::Strong));
  496. AddOutput(new RumbleEffect(fd, RumbleEffect::Motor::Weak));
  497. }
  498. // TODO: Add leds as output devices
  499. // Filter out interesting devices (see description below)
  500. return num_axis >= 2 || num_buttons >= 8;
  501. // On modern linux systems, there are a lot of event devices that aren't controllers.
  502. // For example, the PC Speaker is an event device. Webcams sometimes show up as
  503. // event devices. The power button is an event device.
  504. //
  505. // We don't want these showing up in the list of controllers, so we use this
  506. // heuristic to filter out anything that doesn't smell like a controller:
  507. //
  508. // More than two analog axis:
  509. // Most controllers have at least one stick. This rule will catch all such
  510. // controllers, while ignoring anything with a single axis (like the mouse
  511. // scroll-wheel)
  512. //
  513. // --- OR ---
  514. //
  515. // More than 8 buttons:
  516. // The user might be using a digital only pad such as a NES controller.
  517. // This rule caches such controllers, while eliminating any device with
  518. // only a few buttons, like the power button. Sometimes laptops have devices
  519. // with 5 or 6 special buttons, which is why the threshold is set to 8 to
  520. // match a NES controller.
  521. //
  522. // This heuristic is quite loose. The user may still see weird devices showing up
  523. // as controllers, but it hopefully shouldn't filter out anything they actually
  524. // want to use.
  525. }
  526. const char* evdevDevice::GetUniqueID() const
  527. {
  528. if (m_nodes.empty())
  529. return nullptr;
  530. const auto uniq = libevdev_get_uniq(m_nodes.front().device);
  531. // Some devices (e.g. Mayflash adapter) return an empty string which is not very unique.
  532. if (uniq && std::strlen(uniq) == 0)
  533. return nullptr;
  534. return uniq;
  535. }
  536. const char* evdevDevice::GetPhysicalLocation() const
  537. {
  538. if (m_nodes.empty())
  539. return nullptr;
  540. return libevdev_get_phys(m_nodes.front().device);
  541. }
  542. evdevDevice::evdevDevice(InputBackend* input_backend) : m_input_backend(*input_backend)
  543. {
  544. }
  545. evdevDevice::~evdevDevice()
  546. {
  547. for (auto& node : m_nodes)
  548. {
  549. m_input_backend.RemoveDevnodeObject(node.devnode);
  550. libevdev_free(node.device);
  551. m_input_backend.CloseDescriptor(node.fd);
  552. }
  553. }
  554. void InputBackend::RemoveDevnodeObject(const std::string& node)
  555. {
  556. m_devnode_objects.erase(node);
  557. }
  558. Core::DeviceRemoval evdevDevice::UpdateInput()
  559. {
  560. // Run through all evdev events
  561. // libevdev will keep track of the actual controller state internally which can be queried
  562. // later with libevdev_fetch_event_value()
  563. for (auto& node : m_nodes)
  564. {
  565. int rc = LIBEVDEV_READ_STATUS_SUCCESS;
  566. while (rc >= 0)
  567. {
  568. input_event ev;
  569. if (LIBEVDEV_READ_STATUS_SYNC == rc)
  570. rc = libevdev_next_event(node.device, LIBEVDEV_READ_FLAG_SYNC, &ev);
  571. else
  572. rc = libevdev_next_event(node.device, LIBEVDEV_READ_FLAG_NORMAL, &ev);
  573. }
  574. }
  575. return Core::DeviceRemoval::Keep;
  576. }
  577. bool evdevDevice::IsValid() const
  578. {
  579. for (auto& node : m_nodes)
  580. {
  581. const int current_fd = libevdev_get_fd(node.device);
  582. if (current_fd == -1)
  583. return false;
  584. libevdev* device = nullptr;
  585. if (libevdev_new_from_fd(current_fd, &device) != 0)
  586. {
  587. close(current_fd);
  588. return false;
  589. }
  590. libevdev_free(device);
  591. }
  592. return true;
  593. }
  594. evdevDevice::Effect::Effect(int fd) : m_fd(fd)
  595. {
  596. m_effect.id = -1;
  597. // Left (for wheels):
  598. m_effect.direction = 0x4000;
  599. m_effect.replay.length = RUMBLE_LENGTH_MS;
  600. // FYI: type is set within UpdateParameters.
  601. m_effect.type = DISABLED_EFFECT_TYPE;
  602. }
  603. std::string evdevDevice::ConstantEffect::GetName() const
  604. {
  605. return "Constant";
  606. }
  607. std::string evdevDevice::PeriodicEffect::GetName() const
  608. {
  609. switch (m_effect.u.periodic.waveform)
  610. {
  611. case FF_SQUARE:
  612. return "Square";
  613. case FF_TRIANGLE:
  614. return "Triangle";
  615. case FF_SINE:
  616. return "Sine";
  617. case FF_SAW_UP:
  618. return "Sawtooth Up";
  619. case FF_SAW_DOWN:
  620. return "Sawtooth Down";
  621. default:
  622. return "Unknown";
  623. }
  624. }
  625. std::string evdevDevice::RumbleEffect::GetName() const
  626. {
  627. return (Motor::Strong == m_motor) ? "Strong" : "Weak";
  628. }
  629. void evdevDevice::Effect::SetState(ControlState state)
  630. {
  631. if (UpdateParameters(state))
  632. {
  633. // Update effect if parameters changed.
  634. UpdateEffect();
  635. }
  636. }
  637. void evdevDevice::Effect::UpdateEffect()
  638. {
  639. // libevdev doesn't have nice helpers for forcefeedback
  640. // we will use the file descriptors directly.
  641. // Note: m_effect.type is set within UpdateParameters
  642. // to determine if effect should be playing or not.
  643. if (m_effect.type != DISABLED_EFFECT_TYPE)
  644. {
  645. if (-1 == m_effect.id)
  646. {
  647. // If effect was not uploaded (previously stopped)
  648. // we upload it and start playback
  649. ioctl(m_fd, EVIOCSFF, &m_effect);
  650. input_event play = {};
  651. play.type = EV_FF;
  652. play.code = m_effect.id;
  653. play.value = 1;
  654. static_cast<void>(!write(m_fd, &play, sizeof(play)));
  655. }
  656. else
  657. {
  658. // Effect is already playing. Just update parameters.
  659. ioctl(m_fd, EVIOCSFF, &m_effect);
  660. }
  661. }
  662. else
  663. {
  664. // Stop and remove effect.
  665. ioctl(m_fd, EVIOCRMFF, m_effect.id);
  666. m_effect.id = -1;
  667. }
  668. }
  669. evdevDevice::ConstantEffect::ConstantEffect(int fd) : Effect(fd)
  670. {
  671. m_effect.u.constant = {};
  672. }
  673. evdevDevice::PeriodicEffect::PeriodicEffect(int fd, u16 waveform) : Effect(fd)
  674. {
  675. m_effect.u.periodic = {};
  676. m_effect.u.periodic.waveform = waveform;
  677. m_effect.u.periodic.period = RUMBLE_PERIOD_MS;
  678. m_effect.u.periodic.offset = 0;
  679. m_effect.u.periodic.phase = 0;
  680. }
  681. evdevDevice::RumbleEffect::RumbleEffect(int fd, Motor motor) : Effect(fd), m_motor(motor)
  682. {
  683. m_effect.u.rumble = {};
  684. }
  685. bool evdevDevice::ConstantEffect::UpdateParameters(ControlState state)
  686. {
  687. s16& value = m_effect.u.constant.level;
  688. const s16 old_value = value;
  689. constexpr s16 MAX_VALUE = 0x7fff;
  690. value = s16(state * MAX_VALUE);
  691. m_effect.type = value ? FF_CONSTANT : DISABLED_EFFECT_TYPE;
  692. return value != old_value;
  693. }
  694. bool evdevDevice::PeriodicEffect::UpdateParameters(ControlState state)
  695. {
  696. s16& value = m_effect.u.periodic.magnitude;
  697. const s16 old_value = value;
  698. constexpr s16 MAX_VALUE = 0x7fff;
  699. value = s16(state * MAX_VALUE);
  700. m_effect.type = value ? FF_PERIODIC : DISABLED_EFFECT_TYPE;
  701. return value != old_value;
  702. }
  703. bool evdevDevice::RumbleEffect::UpdateParameters(ControlState state)
  704. {
  705. u16& value = (Motor::Strong == m_motor) ? m_effect.u.rumble.strong_magnitude :
  706. m_effect.u.rumble.weak_magnitude;
  707. const u16 old_value = value;
  708. constexpr u16 MAX_VALUE = 0xffff;
  709. value = u16(state * MAX_VALUE);
  710. m_effect.type = value ? FF_RUMBLE : DISABLED_EFFECT_TYPE;
  711. return value != old_value;
  712. }
  713. evdevDevice::Effect::~Effect()
  714. {
  715. m_effect.type = DISABLED_EFFECT_TYPE;
  716. UpdateEffect();
  717. }
  718. } // namespace ciface::evdev