some input framework attempt
authornotaz <notasas@gmail.com>
Sat, 27 Dec 2008 22:39:00 +0000 (22:39 +0000)
committernotaz <notasas@gmail.com>
Sat, 27 Dec 2008 22:39:00 +0000 (22:39 +0000)
git-svn-id: file:///home/notaz/opt/svn/PicoDrive@621 be3aeb3a-fb24-0410-a615-afba39da0efa

platform/common/input.c [new file with mode: 0644]
platform/common/input.h [new file with mode: 0644]
platform/linux/event.c
platform/linux/event.h

diff --git a/platform/common/input.c b/platform/common/input.c
new file mode 100644 (file)
index 0000000..9e4d5f2
--- /dev/null
@@ -0,0 +1,193 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "input.h"
+#include "../linux/event.h"
+
+typedef struct
+{
+       int drv_id;
+       void *drv_data;
+       int *binds;
+       char *name;
+       int probed:1;
+       int ignore:1;
+} in_dev_t;
+
+#define IN_MAX_DEVS 10
+
+static in_dev_t in_devices[IN_MAX_DEVS];
+static int in_dev_count = 0;
+
+static int in_bind_count(int drv_id)
+{
+       int count = 0;
+#ifdef IN_EVDEV
+       if (drv_id == IN_DRVID_EVDEV)
+               count = in_evdev_bind_count();
+#endif
+       if (count <= 0)
+               printf("input: failed to get bind count for drv %d\n", drv_id);
+
+       return count;
+}
+
+static int *in_alloc_binds(int drv_id)
+{
+       int count, *ret;
+
+       count = in_bind_count(drv_id);
+       if (count <= 0) {
+               printf("input: failed to get bind count for drv %d\n", drv_id);
+               return NULL;
+       }
+
+       ret = malloc(count * sizeof(*ret));
+       return ret;
+}
+
+static void in_free(in_dev_t *dev)
+{
+       if (dev->probed) {
+#ifdef IN_EVDEV
+               if (dev->drv_id == IN_DRVID_EVDEV)
+                       in_evdev_free(dev->drv_data);
+#endif
+       }
+       dev->probed = 0;
+       dev->drv_data = NULL;
+       free(dev->name);
+       dev->name = NULL;
+       free(dev->binds);
+       dev->binds = NULL;
+}
+
+/* to be called by drivers */
+void in_register(const char *nname, int drv_id, void *drv_data)
+{
+       int i, dupe_count = 0, *binds;
+       char name[256], *name_end, *tmp;
+
+       strncpy(name, nname, sizeof(name));
+       name[sizeof(name)-12] = 0;
+       name_end = name + strlen(name);
+
+       for (i = 0; i < in_dev_count; i++)
+       {
+               if (in_devices[i].name == NULL)
+                       continue;
+               if (strcmp(in_devices[i].name, name) == 0)
+               {
+                       if (in_devices[i].probed) {
+                               dupe_count++;
+                               sprintf(name_end, " [%d]", dupe_count);
+                               continue;
+                       }
+                       goto update;
+               }
+       }
+
+       if (i >= IN_MAX_DEVS)
+       {
+               /* try to find unused device */
+               for (i = 0; i < IN_MAX_DEVS; i++)
+                       if (!in_devices[i].probed) break;
+               if (i >= IN_MAX_DEVS) {
+                       printf("input: too many devices, can't add %s\n", name);
+                       return;
+               }
+               in_free(&in_devices[i]);
+       }
+
+       tmp = strdup(name);
+       if (tmp == NULL)
+               return;
+
+       binds = in_alloc_binds(drv_id);
+       if (binds == NULL) {
+               free(tmp);
+               return;
+       }
+
+       in_devices[i].name = tmp;
+       in_devices[i].binds = binds;
+       if (i + 1 > in_dev_count)
+               in_dev_count = i + 1;
+
+       printf("input: new device #%d \"%s\"\n", i, name);
+update:
+       in_devices[i].probed = 1;
+       in_devices[i].drv_id = drv_id;
+       in_devices[i].drv_data = drv_data;
+}
+
+void in_probe(void)
+{
+       int i;
+       for (i = 0; i < in_dev_count; i++)
+               in_devices[i].probed = 0;
+
+#ifdef IN_EVDEV
+       in_evdev_probe();
+#endif
+
+       /* get rid of devs without binds and probes */
+       for (i = 0; i < in_dev_count; i++) {
+               if (!in_devices[i].probed && in_devices[i].binds == NULL) {
+                       in_dev_count--;
+                       if (i < in_dev_count) {
+                               free(in_devices[i].name);
+                               memmove(&in_devices[i], &in_devices[i+1],
+                                       (in_dev_count - i) * sizeof(in_devices[0]));
+                       }
+               }
+       }
+}
+
+void in_clear_binds(const char *devname)
+{
+/*     int count;
+
+       count = in_bind_count(drv_id);
+       if (count <= 0) {
+               printf("input: failed to get bind count for drv %d\n", dev->drv_id);
+               return NULL;
+       }
+*/
+}
+
+int in_update(void)
+{
+       int i, result = 0;
+
+       for (i = 0; i < in_dev_count; i++) {
+               if (in_devices[i].probed && in_devices[i].binds != NULL) {
+#ifdef IN_EVDEV
+                       result |= in_evdev_update(in_devices[i].drv_data, in_devices[i].binds);
+#endif
+               }
+       }
+
+       return result;
+}
+
+void in_init(void)
+{
+       memset(in_devices, 0, sizeof(in_devices));
+       in_dev_count = 0;
+}
+
+int main(void)
+{
+       in_init();
+       in_probe();
+
+       while (1) {
+               in_update();
+               sleep(1);
+       }
+
+       return 0;
+}
+
diff --git a/platform/common/input.h b/platform/common/input.h
new file mode 100644 (file)
index 0000000..4240904
--- /dev/null
@@ -0,0 +1,8 @@
+#define IN_DRVID_EVDEV 1
+
+/* to be called by drivers */
+void in_register(const char *nname, int drv_id, void *drv_data);
+
+void in_init(void);
+void in_probe(void);
+int  in_update(void);
index dea5072..264b182 100644 (file)
@@ -8,24 +8,17 @@
 #include <linux/input.h>
 #include <errno.h>
 
+#include "../common/input.h"
 #include "event.h"
 
-#define NUM_DEVS       8
-#define NUM_KEYS_DOWN  16
-
 #define BIT(x) (keybits[(x)/sizeof(keybits[0])/8] & \
        (1 << ((x) & (sizeof(keybits[0])*8-1))))
 
-static int event_fds[NUM_DEVS];
-static int event_fd_count = 0;
-
-int in_event_init(void)
+int in_evdev_probe(void)
 {
        int i;
 
-       in_event_exit();
-
-       for (i = 0; event_fd_count < NUM_DEVS; i++)
+       for (i = 0;; i++)
        {
                int u, ret, fd, keybits[KEY_MAX/sizeof(int)];
                int support = 0, count = 0;
@@ -39,7 +32,7 @@ int in_event_init(void)
                /* check supported events */
                ret = ioctl(fd, EVIOCGBIT(0, sizeof(support)), &support);
                if (ret == -1) {
-                       printf("in_event: ioctl failed on %s\n", name);
+                       printf("in_evdev: ioctl failed on %s\n", name);
                        goto skip;
                }
 
@@ -48,95 +41,81 @@ int in_event_init(void)
 
                ret = ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(keybits)), keybits);
                if (ret == -1) {
-                       printf("in_event: ioctl failed on %s\n", name);
+                       printf("in_evdev: ioctl failed on %s\n", name);
                        goto skip;
                }
 
-               printf("%s: %08x\n", name, support);
-
                /* check for interesting keys */
                for (u = 0; u < KEY_MAX; u++) {
-                       if (BIT(u) && u != KEY_POWER)
+                       if (BIT(u) && u != KEY_POWER && u != KEY_SLEEP)
                                count++;
                }
 
                if (count == 0)
                        goto skip;
 
-               ioctl(fd, EVIOCGNAME(sizeof(name)), name);
-               printf("event: %d: using \"%s\" with %d events\n",
-                       event_fd_count, name, count);
-               event_fds[event_fd_count++] = fd;
+               strcpy(name, "evdev:");
+               ioctl(fd, EVIOCGNAME(sizeof(name)-6), name+6);
+               printf("in_evdev: found \"%s\" with %d events (type %08x)\n",
+                       name+6, count, support);
+               in_register(name, IN_DRVID_EVDEV, (void *)fd);
                continue;
 
 skip:
                close(fd);
        }
 
-       printf("event: %d devices found.\n", event_fd_count);
        return 0;
 }
 
-void in_event_exit(void)
+void in_evdev_free(void *drv_data)
+{
+       close((int)drv_data);
+}
+
+int in_evdev_bind_count(void)
 {
-       for (; event_fd_count > 0; event_fd_count--)
-               close(event_fds[event_fd_count - 1]);
+       return 512;
 }
 
-int in_event_update(int binds[512])
+int in_evdev_update(void *drv_data, int *binds)
 {
        struct input_event ev[16];
-       int d, rd, ret;
-       int result = 0;
+       int keybits[KEY_MAX/sizeof(int)];
+       int fd = (int)drv_data;
+       int result = 0, changed = 0;
+       int rd, ret, u;
 
-       for (d = 0; d < event_fd_count; d++)
-       {
-               int keybits[KEY_MAX/sizeof(int)];
-               int fd = event_fds[d];
-               int u, changed = 0;
-
-               while (1) {
-                       rd = read(fd, ev, sizeof(ev));
-                       if (rd < (int)sizeof(ev[0])) {
-                               if (errno != EAGAIN)
-                                       perror("event: read failed");
-                               break;
-                       }
-
-                       changed = 1;
+       while (1) {
+               rd = read(fd, ev, sizeof(ev));
+               if (rd < (int)sizeof(ev[0])) {
+                       if (errno != EAGAIN)
+                               perror("in_evdev: read failed");
+                       break;
                }
 
-               if (!changed)
-                       continue;
+               changed = 1;
+       }
 
-               ret = ioctl(fd, EVIOCGKEY(sizeof(keybits)), keybits);
-               if (ret == -1) {
-                       printf("in_event: ioctl failed on %d\n", d);
-                       continue;
-               }
+/*
+       if (!changed)
+               return 0;
+*/
+       ret = ioctl(fd, EVIOCGKEY(sizeof(keybits)), keybits);
+       if (ret == -1) {
+               perror("in_evdev: ioctl failed");
+               return 0;
+       }
 
-               for (u = 0; u < KEY_MAX; u++) {
-                       if (BIT(u)) {
-                               printf(" %d", u);
-                               result |= binds[u];
-                       }
+       printf("#%d: ", fd);
+       for (u = 0; u < KEY_MAX; u++) {
+               if (BIT(u)) {
+                       printf(" %d", u);
+                       result |= binds[u];
                }
-               printf("\n");
        }
+       printf("\n");
 
        return result;
 }
 
-int main()
-{
-       in_event_init();
-
-       while (1) {
-               int b[512];
-               in_event_update(b);
-               sleep(1);
-       }
-
-       return 0;
-}
-
index 9ea887a..fb3cd07 100644 (file)
@@ -1,3 +1,4 @@
-int in_event_init(void);
-void in_event_exit(void);
-int in_event_update(int binds[512]);
+int  in_evdev_probe(void);
+void in_evdev_free(void *drv_data);
+int  in_evdev_bind_count(void);
+int  in_evdev_update(void *drv_data, int *binds);