From 2258f158c46e77d4e62a5ef4814f97c8354a29e3 Mon Sep 17 00:00:00 2001 From: notaz Date: Sat, 27 Dec 2008 22:39:00 +0000 Subject: [PATCH] some input framework attempt git-svn-id: file:///home/notaz/opt/svn/PicoDrive/platform@621 be3aeb3a-fb24-0410-a615-afba39da0efa --- common/input.c | 193 +++++++++++++++++++++++++++++++++++++++++++++++++ common/input.h | 8 ++ linux/event.c | 113 ++++++++++++----------------- linux/event.h | 7 +- 4 files changed, 251 insertions(+), 70 deletions(-) create mode 100644 common/input.c create mode 100644 common/input.h diff --git a/common/input.c b/common/input.c new file mode 100644 index 0000000..9e4d5f2 --- /dev/null +++ b/common/input.c @@ -0,0 +1,193 @@ +#include +#include +#include + +#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/common/input.h b/common/input.h new file mode 100644 index 0000000..4240904 --- /dev/null +++ b/common/input.h @@ -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); diff --git a/linux/event.c b/linux/event.c index dea5072..264b182 100644 --- a/linux/event.c +++ b/linux/event.c @@ -8,24 +8,17 @@ #include #include +#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; -} - diff --git a/linux/event.h b/linux/event.h index 9ea887a..fb3cd07 100644 --- a/linux/event.h +++ b/linux/event.h @@ -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); -- 2.39.5