]> git.sesse.net Git - ultimatescore/blobdiff - client/event_device.cpp
Add some support in the client for reading key events from a non-core IPv6 Buddy.
[ultimatescore] / client / event_device.cpp
diff --git a/client/event_device.cpp b/client/event_device.cpp
new file mode 100644 (file)
index 0000000..26ac820
--- /dev/null
@@ -0,0 +1,175 @@
+#include "event_device.h"
+
+#include <dirent.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <linux/input.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/ioctl.h>
+#include <unistd.h>
+
+#include <QApplication>
+#include <QKeyEvent>
+
+using namespace std;
+
+using std::set;
+using std::pair;
+
+EventDevice::EventDevice(const std::set<std::pair<unsigned, unsigned>> &accepted_usb_ids, QObject *receiver)
+       : accepted_usb_ids(accepted_usb_ids), receiver(receiver)
+{
+       init();
+}
+
+void EventDevice::init()
+{
+       /* scan /dev/input for event devices */
+       DIR *dir = opendir("/dev/input");
+       struct dirent *de;
+       bool found = false;
+       struct input_id found_id;
+       char path[PATH_MAX];
+
+       if (dir == NULL) {
+               perror("/dev/input");
+               exit(1);
+       }
+
+       while ((de = readdir(dir))) {
+               if (strncmp(de->d_name, "event", 5) != 0)
+                       continue;
+
+               sprintf(path, "/dev/input/%s", de->d_name);
+               fd = open(path, O_RDONLY);
+               if (fd == -1) {
+                       fprintf(stderr, "Warning, skipping %s: %s\n",
+                               path, strerror(errno));
+               } else {
+                       struct input_id id;
+                       if (ioctl(fd, EVIOCGID, &id) == -1) {
+                               fprintf(stderr, "ioctl on %s: %s\n",
+                                       path, strerror(errno));
+                               exit(1);
+                       }
+
+                       if (accepted_usb_ids.count({ id.vendor, id.product }) != 0) {
+                               found = true;
+                               found_id = id;
+                               break;
+                       }
+
+                       close(fd);
+               }
+       }
+
+       closedir(dir);
+
+       if (found) {
+               char name[256];
+               ioctl(fd, EVIOCGNAME(255), name);
+
+               fprintf(stderr, "Found device (%04x,%04x) at %s: \"%s\"\n",
+                       found_id.vendor, found_id.product, path, name);
+       } else {
+               fprintf(stderr, "Could not find the USB device\n");
+       }
+}
+
+void EventDevice::start_thread()
+{
+       thr = thread(&EventDevice::thread_func, this);
+       thr.detach();
+}
+
+void EventDevice::thread_func()
+{
+       struct input_event iev;
+       int ret;
+
+       for ( ;; ) {
+               if (fd != -1) {
+                       ret = read(fd, &iev, sizeof(iev));
+                       if (ret != sizeof(iev)) {
+                               perror("read");
+                               fd = -1;
+                       }
+               }
+               if (fd == -1) {
+                       sleep(5);
+                       init();
+                       continue;
+               }
+
+               if (iev.type != EV_KEY)
+                       continue;
+               if (iev.value != 1)
+                       continue;
+
+               QEvent *event = nullptr;
+               switch (iev.code) {
+               case 11:
+                       event = new QKeyEvent(QEvent::KeyPress, Qt::Key_0, Qt::NoModifier, "0");
+                       break;
+               case 2:
+                       event = new QKeyEvent(QEvent::KeyPress, Qt::Key_1, Qt::NoModifier, "1");
+                       break;
+               case 3:
+                       event = new QKeyEvent(QEvent::KeyPress, Qt::Key_2, Qt::NoModifier, "2");
+                       break;
+               case 4:
+                       event = new QKeyEvent(QEvent::KeyPress, Qt::Key_3, Qt::NoModifier, "3");
+                       break;
+               case 5:
+                       event = new QKeyEvent(QEvent::KeyPress, Qt::Key_4, Qt::NoModifier, "4");
+                       break;
+               case 6:
+                       event = new QKeyEvent(QEvent::KeyPress, Qt::Key_5, Qt::NoModifier, "5");
+                       break;
+               case 7:
+                       event = new QKeyEvent(QEvent::KeyPress, Qt::Key_6, Qt::NoModifier, "6");
+                       break;
+               case 8:
+                       event = new QKeyEvent(QEvent::KeyPress, Qt::Key_7, Qt::NoModifier, "7");
+                       break;
+               case 9:
+                       event = new QKeyEvent(QEvent::KeyPress, Qt::Key_8, Qt::NoModifier, "8");
+                       break;
+               case 10:
+                       event = new QKeyEvent(QEvent::KeyPress, Qt::Key_9, Qt::NoModifier, "9");
+                       break;
+               case 30:
+                       event = new QKeyEvent(QEvent::KeyPress, Qt::Key_A, Qt::ShiftModifier, "A");
+                       break;
+               case 48:
+                       event = new QKeyEvent(QEvent::KeyPress, Qt::Key_B, Qt::ShiftModifier, "B");
+                       break;
+               case 46:
+                       event = new QKeyEvent(QEvent::KeyPress, Qt::Key_C, Qt::ShiftModifier, "C");
+                       break;
+               case 32:
+                       event = new QKeyEvent(QEvent::KeyPress, Qt::Key_D, Qt::ShiftModifier, "D");
+                       break;
+               case 18:
+                       event = new QKeyEvent(QEvent::KeyPress, Qt::Key_E, Qt::ShiftModifier, "E");
+                       break;
+               case 33:
+                       event = new QKeyEvent(QEvent::KeyPress, Qt::Key_F, Qt::ShiftModifier, "F");
+                       break;
+               case 14:
+                       event = new QKeyEvent(QEvent::KeyPress, Qt::Key_Backspace, Qt::NoModifier);
+                       break;
+               case 28:
+                       event = new QKeyEvent(QEvent::KeyPress, Qt::Key_Enter, Qt::NoModifier);
+                       break;
+               }
+               if (event) {
+                       QApplication::postEvent(receiver, event);
+               }
+               // printf("iev.type=%d iev.value=%d iev.code=%d\n", iev.type, iev.value, iev.code);
+       }
+}
+