]> Devoid-pointer.net GitWeb - FFBChecker.git/commitdiff
Read devices directly from /dev/input
authorMichal Malý <madcatxster@devoid-pointer.net>
Mon, 6 Jul 2015 23:27:54 +0000 (01:27 +0200)
committerMichal Malý <madcatxster@devoid-pointer.net>
Mon, 6 Jul 2015 23:27:54 +0000 (01:27 +0200)
deviceprober.cpp
deviceprober.h
ffbdevice.cpp
ffbdevice.h
mainwindow.cpp
mainwindow.h

index 3ead1ee0685101f4391551f38ea0773248d8f62a..bbba7e877c75ea9cb77e4a67d0e4af1dfad22e57 100644 (file)
@@ -7,7 +7,7 @@
 #include <fcntl.h>
 #include <unistd.h>
 
-const QDir DeviceProber::s_deviceNodesByID("/dev/input/by-id");
+const QString DeviceProber::DEVICE_NODES_PATH("/dev/input");
 const QString DeviceProber::res_ffbdeviceErrCap("FFB Device error");
 
 DeviceProber::DeviceProber(QObject* parent) :
@@ -15,23 +15,45 @@ DeviceProber::DeviceProber(QObject* parent) :
 {
 }
 
-QStringList DeviceProber::listDevicesByID()
+DeviceProber::DeviceList DeviceProber::listDevices()
 {
-  QStringList devices = DeviceProber::s_deviceNodesByID.entryList(QDir::NoDotAndDotDot);
+  DeviceProber::DeviceList list;
+  QDir devDir(DEVICE_NODES_PATH);
+  //QStringList devices = DeviceProber::s_deviceNodesPath.entryList(QDir::NoDotAndDotDot);
+  QStringList devices = devDir.entryList(QDir::System);
 
-  foreach (const QString s, devices)
-    qDebug() << s;
+  for (const QString& d : devices) {
+    int fd, ret;
+    char deviceName[64];
+    DeviceInfo dinfo;
+    QString devicePath = devDir.absoluteFilePath(d);
 
-  return devices;
+    fd = open(devicePath.toLocal8Bit(), O_RDWR);
+    if (fd == -1) {
+      qDebug() << "Device" << d << "unaccessible" << strerror(errno);
+      continue;
+    }
+
+    dinfo.path = devicePath;
+    ret = ioctl(fd, EVIOCGNAME(64), deviceName);
+    if (ret < 0) {
+      qDebug() << "Cannot get name of device" << d << strerror(errno);
+      dinfo.tag = QString("[%1]").arg(d);
+    } else
+      dinfo.tag = QString("%1 [%2]").arg(deviceName).arg(d);
+
+    list.append(dinfo);
+  }
+
+  return list;
 }
 
-std::shared_ptr<FFBDevice> DeviceProber::openDeviceByID(const QString& id)
+std::shared_ptr<FFBDevice> DeviceProber::openDevice(const QString& path)
 {
-  QString path = DeviceProber::s_deviceNodesByID.absoluteFilePath(id);
   /* Check if the device is already opened */
   for (std::shared_ptr<FFBDevice> dev : m_openedDevices) {
-    if (QString::compare(id, dev->id()) == 0) {
-      qDebug() << "Device" << id << "already opened";
+    if (QString::compare(path, dev->path()) == 0) {
+      qDebug() << "Device" << path << "already opened";
       return dev;
     }
   }
@@ -55,7 +77,7 @@ std::shared_ptr<FFBDevice> DeviceProber::openDeviceByID(const QString& id)
     return nullptr;
   }
 
-  std::shared_ptr<FFBDevice> device(new FFBDevice(fd, id, maxEffectCount));
+  std::shared_ptr<FFBDevice> device(new FFBDevice(fd, path, maxEffectCount));
   if (!device->queryDeviceCapabilities()) {
     QMessageBox::critical(nullptr, res_ffbdeviceErrCap, "Unable to query device capabilities.");
     return nullptr;
index e39ab75aba6c28d8a621b30da55684f0f4dc8052..0314a7ac63c2eb3fccdfac7185b0fbc6066be6a9 100644 (file)
@@ -10,14 +10,20 @@ class DeviceProber : public QObject
 {
   Q_OBJECT
 public:
+  struct DeviceInfo {
+    QString path;
+    QString tag;
+  };
+  typedef QList<DeviceInfo> DeviceList;
+
   explicit DeviceProber(QObject* parent = 0);
-  QStringList listDevicesByID();
-  std::shared_ptr<FFBDevice> openDeviceByID(const QString& id);
+  DeviceList listDevices();
+  std::shared_ptr<FFBDevice> openDevice(const QString& path);
 
 private:
   std::list<std::shared_ptr<FFBDevice>> m_openedDevices;
 
-  static const QDir s_deviceNodesByID;
+  static const QString DEVICE_NODES_PATH;
   static const QString res_ffbdeviceErrCap;
 
 signals:
index 57e58381146137806b65e901577187babc2d4070..0588aaf7976ab99747313ab822918787b0d3bc4c 100644 (file)
@@ -5,11 +5,11 @@
 
 const quint8 FFBDevice::BITS_PER_LONG = sizeof(unsigned long) * 8;
 
-FFBDevice::FFBDevice(const int fd, const QString& id, const int maxEffectCount, QObject* parent) :
+FFBDevice::FFBDevice(const int fd, const QString& path, const int maxEffectCount, QObject* parent) :
   QObject(parent),
   c_fd(fd),
-  c_id(id),
-  c_maxEffectCount(maxEffectCount)
+  c_maxEffectCount(maxEffectCount),
+  c_path(path)
 {
   for (int i = 0; i < maxEffectCount; i++)
     m_effects.push_back(FFBEffectFactory::createEffect(FFBEffectTypes::NONE));
index bcf05b7afcbdee6cc8bd8549019c67669c08e836..b1171b4bccd03a1c4daf8d26cf56e0cfb8e0c640 100644 (file)
@@ -16,7 +16,7 @@ class FFBDevice : public QObject
   Q_OBJECT
 public:
 
-  explicit FFBDevice(const int fd, const QString& id, const int maxEffectCount, QObject* parent = 0);
+  explicit FFBDevice(const int fd, const QString& path, const int maxEffectCount, QObject* parent = 0);
   QStringList availableConditionSubtypesList() const;
   QStringList availableEffectsList() const;
   QStringList availableWaveformsList() const;
@@ -30,8 +30,8 @@ public:
   FFBEffectTypes effectTypeByEffectIdx(const int idx) const;
   bool hasEffect(FFBEffectTypes id) const;
   bool hasPeriodicWaveform(PeriodicWaveforms id) const;
-  inline const QString& id() const { return c_id; }
   inline int maxEffectCount() const { return c_maxEffectCount; }
+  inline const QString& path() const { return c_path; }
   bool queryDeviceCapabilities();
   bool removeAndEraseEffect(const int idx);
   bool startEffect(const int idx, FFBEffectTypes type, std::shared_ptr<FFBEffectParameters> params);
@@ -48,8 +48,8 @@ private:
   std::vector<std::shared_ptr<FFBEffect>> m_effects;
 
   const int c_fd;
-  const QString c_id;
   const int c_maxEffectCount;
+  const QString c_path;
 
   static inline unsigned long longIdx(unsigned long bit) { return bit / BITS_PER_LONG; }
   static inline unsigned long offset(unsigned long bit) { return bit % BITS_PER_LONG; }
index bff315cac846eee0b0e015079bb0039e9dffab69..dee56e5f3303de847aef7a289b6709a69a90fd27 100644 (file)
@@ -33,7 +33,7 @@ MainWindow::MainWindow(std::shared_ptr<DeviceProber> prober, const QString& titl
     ui->ql_noChecksWarning->setHidden(true);
 
   fillDeviceList();
-  connect(ui->cbox_devices, SIGNAL(activated(const QString&)), this, SLOT(onDeviceSelected(const QString&)));
+  connect(ui->cbox_devices, SIGNAL(activated(const int)), this, SLOT(onDeviceSelected(const int)));
   connect(ui->cbox_effectSlots, SIGNAL(activated(const int)), this, SLOT(onEffectSlotSelected(const int)));
   connect(ui->cbox_effectTypes, SIGNAL(activated(const int)), this, SLOT(onEffectTypeSelected(const int)));
   connect(ui->qpb_refreshDevices, SIGNAL(clicked()), this, SLOT(onRefreshDevicesClicked()));
@@ -63,7 +63,9 @@ EffectSettings* MainWindow::effectSettingsByType(FFBEffectTypes type)
 void MainWindow::fillDeviceList()
 {
   ui->cbox_devices->clear();
-  ui->cbox_devices->addItems(m_prober->listDevicesByID());
+
+  for (const DeviceProber::DeviceInfo& dinfo : m_prober->listDevices())
+    ui->cbox_devices->addItem(dinfo.tag, dinfo.path);
 }
 
 void MainWindow::fillEffectSlotsList(const int idx)
@@ -79,10 +81,11 @@ void MainWindow::fillEffectTypesList(const QStringList& list)
   ui->cbox_effectTypes->addItems(list);
 }
 
-void MainWindow::onDeviceSelected(const QString& id)
+void MainWindow::onDeviceSelected(const int idx)
 {
+  QString path = ui->cbox_devices->itemData(idx, Qt::UserRole).toString();
   ui->cbox_effectSlots->clear();
-  m_activeDevice = m_prober->openDeviceByID(id);
+  m_activeDevice = m_prober->openDevice(path);
 
   if (m_activeDevice == nullptr)
     return;
index 33687ce477050d73d6072e0f7d7a76cf9bfc0701..73fe41af0975cc7000b5952dfa636f076b8c84e4 100644 (file)
@@ -53,7 +53,7 @@ private:
   static const QString res_inputFormatErrCap;
 
 private slots:
-  void onDeviceSelected(const QString& id);
+  void onDeviceSelected(const int idx);
   void onEffectSlotSelected(const int idx);
   void onEffectTypeSelected(const int idx);
   void onRefreshDevicesClicked();