]> git.sesse.net Git - ultimatescore/blob - client/event_device.cpp
Make the roster scripts executable.
[ultimatescore] / client / event_device.cpp
1 #include "event_device.h"
2
3 #include <dirent.h>
4 #include <errno.h>
5 #include <fcntl.h>
6 #include <limits.h>
7 #include <linux/input.h>
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <string.h>
11 #include <sys/ioctl.h>
12 #include <unistd.h>
13
14 #include <QApplication>
15 #include <QKeyEvent>
16
17 using namespace std;
18
19 using std::set;
20 using std::pair;
21
22 EventDevice::EventDevice(const std::set<std::pair<unsigned, unsigned>> &accepted_usb_ids, QObject *receiver)
23         : accepted_usb_ids(accepted_usb_ids), receiver(receiver)
24 {
25         init();
26 }
27
28 void EventDevice::init()
29 {
30         /* scan /dev/input for event devices */
31         DIR *dir = opendir("/dev/input");
32         struct dirent *de;
33         bool found = false;
34         struct input_id found_id;
35         char path[PATH_MAX];
36
37         if (dir == NULL) {
38                 perror("/dev/input");
39                 exit(1);
40         }
41
42         while ((de = readdir(dir))) {
43                 if (strncmp(de->d_name, "event", 5) != 0)
44                         continue;
45
46                 sprintf(path, "/dev/input/%s", de->d_name);
47                 fd = open(path, O_RDONLY);
48                 if (fd == -1) {
49                         fprintf(stderr, "Warning, skipping %s: %s\n",
50                                 path, strerror(errno));
51                 } else {
52                         struct input_id id;
53                         if (ioctl(fd, EVIOCGID, &id) == -1) {
54                                 fprintf(stderr, "ioctl on %s: %s\n",
55                                         path, strerror(errno));
56                                 exit(1);
57                         }
58
59                         if (accepted_usb_ids.count({ id.vendor, id.product }) != 0) {
60                                 found = true;
61                                 found_id = id;
62                                 break;
63                         }
64
65                         close(fd);
66                 }
67         }
68
69         closedir(dir);
70
71         if (found) {
72                 char name[256];
73                 ioctl(fd, EVIOCGNAME(255), name);
74
75                 fprintf(stderr, "Found device (%04x,%04x) at %s: \"%s\"\n",
76                         found_id.vendor, found_id.product, path, name);
77         } else {
78                 fprintf(stderr, "Could not find the USB device\n");
79         }
80 }
81
82 void EventDevice::start_thread()
83 {
84         thr = thread(&EventDevice::thread_func, this);
85         thr.detach();
86 }
87
88 void EventDevice::thread_func()
89 {
90         struct input_event iev;
91         int ret;
92
93         for ( ;; ) {
94                 if (fd != -1) {
95                         ret = read(fd, &iev, sizeof(iev));
96                         if (ret != sizeof(iev)) {
97                                 perror("read");
98                                 fd = -1;
99                         }
100                 }
101                 if (fd == -1) {
102                         sleep(5);
103                         init();
104                         continue;
105                 }
106
107                 if (iev.type != EV_KEY)
108                         continue;
109                 if (iev.value != 1)
110                         continue;
111
112                 QEvent *event = nullptr;
113                 switch (iev.code) {
114                 case 11:
115                         event = new QKeyEvent(QEvent::KeyPress, Qt::Key_0, Qt::NoModifier, "0");
116                         break;
117                 case 2:
118                         event = new QKeyEvent(QEvent::KeyPress, Qt::Key_1, Qt::NoModifier, "1");
119                         break;
120                 case 3:
121                         event = new QKeyEvent(QEvent::KeyPress, Qt::Key_2, Qt::NoModifier, "2");
122                         break;
123                 case 4:
124                         event = new QKeyEvent(QEvent::KeyPress, Qt::Key_3, Qt::NoModifier, "3");
125                         break;
126                 case 5:
127                         event = new QKeyEvent(QEvent::KeyPress, Qt::Key_4, Qt::NoModifier, "4");
128                         break;
129                 case 6:
130                         event = new QKeyEvent(QEvent::KeyPress, Qt::Key_5, Qt::NoModifier, "5");
131                         break;
132                 case 7:
133                         event = new QKeyEvent(QEvent::KeyPress, Qt::Key_6, Qt::NoModifier, "6");
134                         break;
135                 case 8:
136                         event = new QKeyEvent(QEvent::KeyPress, Qt::Key_7, Qt::NoModifier, "7");
137                         break;
138                 case 9:
139                         event = new QKeyEvent(QEvent::KeyPress, Qt::Key_8, Qt::NoModifier, "8");
140                         break;
141                 case 10:
142                         event = new QKeyEvent(QEvent::KeyPress, Qt::Key_9, Qt::NoModifier, "9");
143                         break;
144                 case 30:
145                         event = new QKeyEvent(QEvent::KeyPress, Qt::Key_A, Qt::ShiftModifier, "A");
146                         break;
147                 case 48:
148                         event = new QKeyEvent(QEvent::KeyPress, Qt::Key_B, Qt::ShiftModifier, "B");
149                         break;
150                 case 46:
151                         event = new QKeyEvent(QEvent::KeyPress, Qt::Key_C, Qt::ShiftModifier, "C");
152                         break;
153                 case 32:
154                         event = new QKeyEvent(QEvent::KeyPress, Qt::Key_D, Qt::ShiftModifier, "D");
155                         break;
156                 case 18:
157                         event = new QKeyEvent(QEvent::KeyPress, Qt::Key_E, Qt::ShiftModifier, "E");
158                         break;
159                 case 33:
160                         event = new QKeyEvent(QEvent::KeyPress, Qt::Key_F, Qt::ShiftModifier, "F");
161                         break;
162                 case 14:
163                         event = new QKeyEvent(QEvent::KeyPress, Qt::Key_Backspace, Qt::NoModifier);
164                         break;
165                 case 28:
166                         event = new QKeyEvent(QEvent::KeyPress, Qt::Key_Enter, Qt::NoModifier);
167                         break;
168                 }
169                 if (event) {
170                         QApplication::postEvent(receiver, event);
171                 }
172                 // printf("iev.type=%d iev.value=%d iev.code=%d\n", iev.type, iev.value, iev.code);
173         }
174 }
175