Implement mouse cursor

Signed-off-by: Vojtech Bocek <vbocek@gmail.com>

Change-Id: I66d6db7b3ed9cca50b469d125b36224332e06913
diff --git a/minuitwrp/events.c b/minuitwrp/events.c
index aecaf8f..94942ba 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 @@
 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;
@@ -239,12 +245,41 @@
     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))) {
@@ -260,23 +295,32 @@
             /* 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)
@@ -629,9 +673,25 @@
 {
     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++) {
@@ -644,6 +704,8 @@
                 }
             }
         }
+
+        usleep(1000);
     } while(dont_wait == 0);
 
     return -1;