#include <errno.h>
#include <stdio.h>
#include <dirent.h>
+#include <signal.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <stdbool.h>
#include <sys/poll.h>
+#include <sys/signalfd.h>
#include <linux/input.h>
#include "input-events.h"
-#define MAX_DEVICES 16
-#define MAX_MISC_FDS 16
+#define MAX_INPUTS 32
#define BITS_PER_LONG (sizeof(unsigned long) * 8)
#define BITS_TO_LONGS(x) (((x) + BITS_PER_LONG - 1) / BITS_PER_LONG)
#define test_bit(bit, array) \
((array)[(bit) / BITS_PER_LONG] & (1 << ((bit) % BITS_PER_LONG)))
-static struct pollfd ev_fds[MAX_DEVICES + MAX_MISC_FDS];
+static struct pollfd ev_fds[MAX_INPUTS];
static unsigned ev_count = 0;
-static unsigned ev_misc_count = 0;
-bool ev_init(void)
+static unsigned signalfd_idx = -1;
+
+#define IS_SIGNAL_EVENT(x) (x == signalfd_idx)
+
+static bool ev_signal_init(void)
+{
+ sigset_t mask;
+
+ if (ev_count >= MAX_INPUTS)
+ return false;
+
+ sigemptyset(&mask);
+ sigaddset(&mask, SIGINT);
+ if (sigprocmask(SIG_BLOCK, &mask, NULL) == -1) {
+ perror("sigprocmask");
+ return false;
+ }
+
+ ev_fds[ev_count].fd = signalfd(-1, &mask, 0);
+ ev_fds[ev_count].events = POLLIN;
+ if (ev_fds[ev_count].fd == -1) {
+ perror("signalfd");
+ return false;
+ }
+ signalfd_idx = ev_count++;
+
+ return true;
+}
+
+static bool ev_input_init(void)
{
DIR *dir;
struct dirent *de;
int fd;
+ int t = ev_count;
dir = opendir("/dev/input");
if (!dir) {
while ((de = readdir(dir))) {
unsigned long ev_bits[BITS_TO_LONGS(EV_MAX)];
- /* fprintf(stderr,"/dev/input/%s\n", de->d_name);*/
+ /* fprintf(stderr,"/dev/input/%s\n", de->d_name);*/
if (strncmp(de->d_name, "event", 5))
continue;
ev_fds[ev_count].fd = fd;
ev_fds[ev_count].events = POLLIN;
ev_count++;
- if (ev_count == MAX_DEVICES)
+ if (ev_count == MAX_INPUTS)
break;
}
closedir(dir);
- if (ev_count == 0) {
+ if (ev_count == t) {
printf("No input devices found.\n");
return false;
}
return true;
}
+bool ev_init(void)
+{
+ return ev_input_init() && ev_signal_init();
+}
+
void ev_exit(void)
{
while (ev_count > 0)
close(ev_fds[--ev_count].fd);
-
- ev_misc_count = 0;
}
static user_action last_action = ACTION_NONE;
int r;
struct input_event ev;
+ if (IS_SIGNAL_EVENT(n)) { /* signalfd */
+ struct signalfd_siginfo fdsi;
+ r = read(ev_fds[n].fd, &fdsi, sizeof(fdsi));
+ if (r != sizeof(fdsi)) {
+ perror("read");
+ return false;
+ }
+ if (fdsi.ssi_signo == SIGINT)
+ return false;
+ continue;
+ }
+
r = read(ev_fds[n].fd, &ev, sizeof(ev));
if (r != sizeof(ev))
continue;