diff options
Diffstat (limited to 'minuitwrp/events.c')
-rw-r--r-- | minuitwrp/events.c | 80 |
1 files changed, 72 insertions, 8 deletions
diff --git a/minuitwrp/events.c b/minuitwrp/events.c index 73369a2cc..94942ba7b 100644 --- a/minuitwrp/events.c +++ b/minuitwrp/events.c @@ -20,8 +20,11 @@ #include <dirent.h> #include <sys/poll.h> #include <limits.h> - #include <linux/input.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> + #include "../common.h" @@ -95,6 +98,9 @@ struct ev { static struct pollfd ev_fds[MAX_DEVICES]; static struct ev evs[MAX_DEVICES]; static unsigned ev_count = 0; +static struct timeval lastInputStat; +static unsigned long lastInputMTime; +static int has_mouse = 0; static inline int ABS(int x) { return x<0?-x:x; @@ -106,6 +112,8 @@ int vibrate(int timeout_ms) int fd; int ret; + if (timeout_ms > 10000) timeout_ms = 1000; + fd = open(VIBRATOR_TIMEOUT_FILE, O_WRONLY); if (fd < 0) return -1; @@ -237,12 +245,41 @@ static int vk_init(struct ev *e) return 0; } +#define BITS_PER_LONG (sizeof(long) * 8) +#define NBITS(x) ((((x)-1)/BITS_PER_LONG)+1) +#define OFF(x) ((x)%BITS_PER_LONG) +#define LONG(x) ((x)/BITS_PER_LONG) +#define test_bit(bit, array) ((array[LONG(bit)] >> OFF(bit)) & 1) +static void check_mouse(int fd) +{ + if(has_mouse) + return; + + unsigned long bit[EV_MAX][NBITS(KEY_MAX)]; + memset(bit, 0, sizeof(bit)); + ioctl(fd, EVIOCGBIT(0, EV_MAX), bit[0]); + + if(!test_bit(EV_REL, bit[0])) + return; + + ioctl(fd, EVIOCGBIT(EV_REL, KEY_MAX), bit[EV_REL]); + if(test_bit(REL_X, bit[EV_REL]) && test_bit(REL_Y, bit[EV_REL])) + has_mouse = 1; +} + +int ev_has_mouse(void) +{ + return has_mouse; +} + int ev_init(void) { DIR *dir; struct dirent *de; int fd; + has_mouse = 0; + dir = opendir("/dev/input"); if(dir != 0) { while((de = readdir(dir))) { @@ -258,23 +295,32 @@ int ev_init(void) /* Load virtualkeys if there are any */ vk_init(&evs[ev_count]); + check_mouse(fd); + ev_count++; if(ev_count == MAX_DEVICES) break; } + closedir(dir); } + struct stat st; + if(stat("/dev/input", &st) >= 0) + lastInputMTime = st.st_mtime; + gettimeofday(&lastInputStat, NULL); + return 0; } void ev_exit(void) { - while (ev_count-- > 0) { - if (evs[ev_count].vk_count) { - free(evs[ev_count].vks); - evs[ev_count].vk_count = 0; + while (ev_count-- > 0) { + if (evs[ev_count].vk_count) { + free(evs[ev_count].vks); + evs[ev_count].vk_count = 0; + } + close(ev_fds[ev_count].fd); } - close(ev_fds[ev_count].fd); - } + ev_count = 0; } static int vk_inside_display(__s32 value, struct input_absinfo *info, int screen_size) @@ -627,9 +673,25 @@ int ev_get(struct input_event *ev, unsigned dont_wait) { int r; unsigned n; + struct timeval curr; do { - r = poll(ev_fds, ev_count, dont_wait ? 0 : -1); + gettimeofday(&curr, NULL); + if(curr.tv_sec - lastInputStat.tv_sec >= 2) + { + struct stat st; + stat("/dev/input", &st); + if (st.st_mtime > lastInputMTime) + { + LOGI("Reloading input devices\n"); + ev_exit(); + ev_init(); + lastInputMTime = st.st_mtime; + } + lastInputStat = curr; + } + + r = poll(ev_fds, ev_count, 0); if(r > 0) { for(n = 0; n < ev_count; n++) { @@ -642,6 +704,8 @@ int ev_get(struct input_event *ev, unsigned dont_wait) } } } + + usleep(1000); } while(dont_wait == 0); return -1; |