From 34581c95f808322ecb29e0931ba8f5c879cc89b6 Mon Sep 17 00:00:00 2001 From: notaz Date: Tue, 30 Dec 2008 16:53:18 +0000 Subject: [PATCH] more input wip git-svn-id: file:///home/notaz/opt/svn/PicoDrive/platform@623 be3aeb3a-fb24-0410-a615-afba39da0efa --- common/common.h | 22 +++++------ common/input.c | 48 ++++++++++++++++++------ common/input.h | 4 +- linux/in_evdev.c | 98 +++++++++++++++++++++++++++++++++++++++++++++++- linux/in_evdev.h | 15 ++++++++ 5 files changed, 163 insertions(+), 24 deletions(-) diff --git a/common/common.h b/common/common.h index 0b7a20f..88983ce 100644 --- a/common/common.h +++ b/common/common.h @@ -106,17 +106,17 @@ void menu_draw_end(void); #include "../gp2x/gp2x.h" -#define PBTN_UP 0 -#define PBTN_DOWN 0 -#define PBTN_LEFT 0 -#define PBTN_RIGHT 0 - -#define PBTN_NORTH 0 -#define PBTN_SOUTH 0 -#define PBTN_WEST 0 -#define PBTN_EAST 0 -#define PBTN_L 0 -#define PBTN_R 0 +#define PBTN_UP (1 << 0) +#define PBTN_DOWN (1 << 1) +#define PBTN_LEFT (1 << 2) +#define PBTN_RIGHT (1 << 3) + +#define PBTN_NORTH (1 << 4) +#define PBTN_SOUTH (1 << 5) +#define PBTN_WEST (1 << 6) +#define PBTN_EAST (1 << 7) +#define PBTN_L (1 << 8) +#define PBTN_R (1 << 9) unsigned long wait_for_input(unsigned long interesting); void gp2x_pd_clone_buffer2(void); diff --git a/common/input.c b/common/input.c index 9e4d5f2..77d9f3a 100644 --- a/common/input.c +++ b/common/input.c @@ -3,7 +3,7 @@ #include #include "input.h" -#include "../linux/event.h" +#include "../linux/in_evdev.h" typedef struct { @@ -23,10 +23,8 @@ 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); @@ -50,10 +48,8 @@ static int *in_alloc_binds(int drv_id) 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; @@ -128,9 +124,7 @@ void in_probe(void) 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++) { @@ -163,15 +157,44 @@ int in_update(void) 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 + if (in_devices[i].drv_id == IN_DRVID_EVDEV) + result |= in_evdev_update(in_devices[i].drv_data, in_devices[i].binds); } } return result; } +/* + * update with wait for a press, return bitfield of BTN_* + * only can use 1 drv here.. + */ +int in_update_menu(void) +{ + int result = 0; +#ifdef IN_EVDEV + void *data[IN_MAX_DEVS]; + int i, count = 0; + + for (i = 0; i < in_dev_count; i++) { + if (in_devices[i].probed) + data[count++] = in_devices[i].drv_data; + } + + if (count == 0) { + /* don't deadlock, fail */ + printf("input: failed to find devices to read\n"); + exit(1); + } + + result = in_evdev_update_menu(data, count); +#else +#error no menu read handlers +#endif + + return result; +} + void in_init(void) { memset(in_devices, 0, sizeof(in_devices)); @@ -180,11 +203,14 @@ void in_init(void) int main(void) { + int ret; + in_init(); in_probe(); while (1) { - in_update(); + ret = in_update_menu(); + printf("%08x\n", ret); sleep(1); } diff --git a/common/input.h b/common/input.h index 4240904..0110e98 100644 --- a/common/input.h +++ b/common/input.h @@ -1,4 +1,6 @@ -#define IN_DRVID_EVDEV 1 +enum { + IN_DRVID_EVDEV = 1, +}; /* to be called by drivers */ void in_register(const char *nname, int drv_id, void *drv_data); diff --git a/linux/in_evdev.c b/linux/in_evdev.c index 264b182..9f0e231 100644 --- a/linux/in_evdev.c +++ b/linux/in_evdev.c @@ -8,8 +8,9 @@ #include #include +#include "../common/common.h" #include "../common/input.h" -#include "event.h" +#include "in_evdev.h" #define BIT(x) (keybits[(x)/sizeof(keybits[0])/8] & \ (1 << ((x) & (sizeof(keybits[0])*8-1)))) @@ -119,3 +120,98 @@ int in_evdev_update(void *drv_data, int *binds) return result; } +int in_evdev_update_menu(void **data, int count) +{ + const int *fds = (const int *)data; + static int result = 0; + int i, ret, fdmax = -1; + int oldresult = result; + long flags; + + /* switch to blocking mode */ + for (i = 0; i < count; i++) { + if (fds[i] > fdmax) fdmax = fds[i]; + + flags = (long)fcntl(fds[i], F_GETFL); + if ((int)flags == -1) { + perror("in_evdev: F_GETFL fcntl failed"); + continue; + } + flags &= ~O_NONBLOCK; + ret = fcntl(fds[i], F_SETFL, flags); + if (ret == -1) + perror("in_evdev: F_SETFL fcntl failed"); + } + + while (1) + { + struct input_event ev[64]; + int fd, rd; + fd_set fdset; + + FD_ZERO(&fdset); + for (i = 0; i < count; i++) + FD_SET(fds[i], &fdset); + + ret = select(fdmax + 1, &fdset, NULL, NULL, NULL); + if (ret == -1) + { + perror("in_evdev: select failed"); + sleep(1); + return 0; + } + + for (i = 0; i < count; i++) + if (FD_ISSET(fds[i], &fdset)) + fd = fds[i]; + + rd = read(fd, ev, sizeof(ev[0]) * 64); + if (rd < (int) sizeof(ev[0])) { + perror("in_evdev: error reading"); + sleep(1); + return 0; + } + + #define mapkey(o,k) \ + case o: \ + if (ev[i].value) result |= k; \ + else result &= ~k; \ + break + for (i = 0; i < rd / sizeof(ev[0]); i++) + { + if (ev[i].type != EV_KEY || ev[i].value < 0 || ev[i].value > 1) + continue; + + switch (ev[i].code) { + /* keyboards */ + mapkey(KEY_UP, PBTN_UP); + mapkey(KEY_DOWN, PBTN_DOWN); + mapkey(KEY_LEFT, PBTN_LEFT); + mapkey(KEY_RIGHT, PBTN_RIGHT); + mapkey(KEY_ENTER, PBTN_EAST); + mapkey(KEY_ESC, PBTN_SOUTH); + } + } + #undef mapkey + + if (oldresult != result) break; + } + + /* switch back to non-blocking mode */ + for (i = 0; i < count; i++) { + if (fds[i] > fdmax) fdmax = fds[i]; + + flags = (long)fcntl(fds[i], F_GETFL); + if ((int)flags == -1) { + perror("in_evdev: F_GETFL fcntl failed"); + continue; + } + flags |= O_NONBLOCK; + ret = fcntl(fds[i], F_SETFL, flags); + if (ret == -1) + perror("in_evdev: F_SETFL fcntl failed"); + } + + return result; +} + diff --git a/linux/in_evdev.h b/linux/in_evdev.h index fb3cd07..8bd1b99 100644 --- a/linux/in_evdev.h +++ b/linux/in_evdev.h @@ -1,4 +1,19 @@ + +#ifdef IN_EVDEV + 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); + +#else + +#define in_evdev_probe() -1 +#define in_evdev_free(x) +#define in_evdev_bind_count() 0 +#define in_evdev_update(x,y) 0 + +#endif + +int in_evdev_update_menu(void **data, int count); + -- 2.39.5