From 7201dc73fb3b0c4cfc2cf548e3f9f7d0385b9bda Mon Sep 17 00:00:00 2001 From: notaz Date: Mon, 16 Feb 2009 15:09:05 +0000 Subject: [PATCH] move select from evdev to upper level git-svn-id: file:///home/notaz/opt/svn/PicoDrive@636 be3aeb3a-fb24-0410-a615-afba39da0efa --- platform/common/input.c | 91 +++++++++++++++++++--------- platform/common/input.h | 4 +- platform/linux/in_evdev.c | 121 ++++++++++++++------------------------ platform/linux/in_evdev.h | 3 +- 4 files changed, 112 insertions(+), 107 deletions(-) diff --git a/platform/common/input.c b/platform/common/input.c index 19912444..163311ba 100644 --- a/platform/common/input.c +++ b/platform/common/input.c @@ -9,6 +9,7 @@ typedef struct { int drv_id; + int drv_fd_hnd; void *drv_data; char *name; int *binds; @@ -61,7 +62,7 @@ static void in_free(in_dev_t *dev) } /* to be called by drivers */ -void in_register(const char *nname, int drv_id, void *drv_data) +void in_register(const char *nname, int drv_id, int drv_fd_hnd, void *drv_data) { int i, ret, dupe_count = 0, *binds; char name[256], *name_end, *tmp; @@ -116,6 +117,7 @@ void in_register(const char *nname, int drv_id, void *drv_data) update: in_devices[i].probed = 1; in_devices[i].drv_id = drv_id; + in_devices[i].drv_fd_hnd = drv_fd_hnd; in_devices[i].drv_data = drv_data; if (in_devices[i].binds != NULL) { @@ -150,6 +152,7 @@ void in_probe(void) } } +/* async update */ int in_update(void) { int i, result = 0; @@ -170,19 +173,6 @@ int in_update(void) return result; } -static void **in_collect_drvdata(int drv_id, int *count) -{ - static void *data[IN_MAX_DEVS]; - int i; - - for (*count = i = 0; i < in_dev_count; i++) { - if (in_devices[i].drv_id == drv_id && in_devices[i].probed) - data[(*count)++] = in_devices[i].drv_data; - } - - return data; -} - static int menu_key_state = 0; void in_set_blocking(int is_blocking) @@ -199,39 +189,84 @@ void in_set_blocking(int is_blocking) in_update_keycode(NULL, NULL, 0); } +/* TODO: move.. */ +#include + /* - * update with wait for a press, return keycode - * only can use 1 drv here.. + * update with wait for a press, always return some keycode */ int in_update_keycode(int *dev_id_out, int *is_down_out, int timeout_ms) { int result = 0, dev_id = 0, is_down, result_menu; -#ifdef IN_EVDEV - void **data; - int i, id = 0, count = 0; + int fds_hnds[IN_MAX_DEVS]; + int i, ret, count = 0; + in_drv_t *drv; + + for (i = 0; i < in_dev_count; i++) { + if (in_devices[i].probed) + fds_hnds[count++] = in_devices[i].drv_fd_hnd; + } - data = in_collect_drvdata(IN_DRVID_EVDEV, &count); if (count == 0) { /* don't deadlock, fail */ printf("input: failed to find devices to read\n"); exit(1); } - result = in_evdev_update_keycode(data, count, &id, &is_down, timeout_ms); +again: + /* TODO: move this block to platform/linux */ + { + struct timeval tv, *timeout = NULL; + int fdmax = -1; + fd_set fdset; + + if (timeout_ms >= 0) { + tv.tv_sec = timeout_ms / 1000; + tv.tv_usec = (timeout_ms % 1000) * 1000; + timeout = &tv; + } - for (i = id; i < in_dev_count; i++) { - if (in_devices[i].drv_data == data[id]) { + FD_ZERO(&fdset); + for (i = 0; i < count; i++) { + if (fds_hnds[i] > fdmax) fdmax = fds_hnds[i]; + FD_SET(fds_hnds[i], &fdset); + } + + ret = select(fdmax + 1, &fdset, NULL, NULL, timeout); + if (ret == -1) + { + perror("input: select failed"); + sleep(1); + return 0; + } + + if (ret == 0) + return 0; /* timeout */ + + for (i = 0; i < count; i++) + if (FD_ISSET(fds_hnds[i], &fdset)) + ret = fds_hnds[i]; + } + + for (i = 0; i < in_dev_count; i++) { + if (in_devices[i].drv_fd_hnd == ret) { dev_id = i; break; } } -#else -#error no menu read handlers -#endif + + drv = &DRV(in_devices[dev_id].drv_id); + result = drv->update_keycode(in_devices[dev_id].drv_data, &is_down); + + /* update_keycode() might return 0 when some not interesting + * event happened, like sync event for evdev. + * XXX: timeout restarts.. */ + if (result == 0) + goto again; /* keep track of menu key state, to allow mixing * in_update_keycode() and in_menu_wait_any() calls */ - result_menu = DRV(in_devices[dev_id].drv_id).menu_translate(result); + result_menu = drv->menu_translate(result); if (result_menu != 0) { if (is_down) menu_key_state |= result_menu; @@ -571,6 +606,7 @@ static int in_def_get_bind_count(void) { return 0; } static void in_def_get_def_binds(int *binds) {} static int in_def_clean_binds(void *drv_data, int *binds) { return 0; } static void in_def_set_blocking(void *data, int y) {} +static int in_def_update_keycode(void *drv_data, int *is_down) { return 0; } static int in_def_menu_translate(int keycode) { return keycode; } static int in_def_get_key_code(const char *key_name) { return 0; } static const char *in_def_get_key_name(int keycode) { return NULL; } @@ -591,6 +627,7 @@ void in_init(void) in_drivers[i].get_def_binds = in_def_get_def_binds; in_drivers[i].clean_binds = in_def_clean_binds; in_drivers[i].set_blocking = in_def_set_blocking; + in_drivers[i].update_keycode = in_def_update_keycode; in_drivers[i].menu_translate = in_def_menu_translate; in_drivers[i].get_key_code = in_def_get_key_code; in_drivers[i].get_key_name = in_def_get_key_name; diff --git a/platform/common/input.h b/platform/common/input.h index 8a1cdea4..71ca9997 100644 --- a/platform/common/input.h +++ b/platform/common/input.h @@ -3,6 +3,7 @@ enum { IN_DRVID_UNKNOWN = 0, IN_DRVID_EVDEV, + IN_DRVID_GP2X, IN_DRVID_COUNT }; @@ -14,6 +15,7 @@ typedef struct { void (*get_def_binds)(int *binds); int (*clean_binds)(void *drv_data, int *binds); void (*set_blocking)(void *data, int y); + int (*update_keycode)(void *drv_data, int *is_down); int (*menu_translate)(int keycode); int (*get_key_code)(const char *key_name); const char * (*get_key_name)(int keycode); @@ -21,7 +23,7 @@ typedef struct { /* to be called by drivers */ -void in_register(const char *nname, int drv_id, void *drv_data); +void in_register(const char *nname, int drv_id, int fd_hnd, void *drv_data); void in_init(void); void in_probe(void); diff --git a/platform/linux/in_evdev.c b/platform/linux/in_evdev.c index a89500f1..984333c8 100644 --- a/platform/linux/in_evdev.c +++ b/platform/linux/in_evdev.c @@ -195,7 +195,7 @@ no_abs: 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, dev); + in_register(name, IN_DRVID_EVDEV, fd, dev); continue; skip: @@ -295,95 +295,61 @@ static void in_evdev_set_blocking(void *drv_data, int y) perror("in_evdev: F_SETFL fcntl failed"); } -int in_evdev_update_keycode(void **data, int dcount, int *which, int *is_down, int timeout_ms) +static int in_evdev_update_keycode(void *data, int *is_down) { - in_evdev_t **devs = (in_evdev_t **)data; - struct timeval tv, *timeout = NULL; - int i, fdmax = -1; - - if (timeout_ms >= 0) { - tv.tv_sec = timeout_ms / 1000; - tv.tv_usec = (timeout_ms % 1000) * 1000; - timeout = &tv; - } + in_evdev_t *dev = data; + struct input_event ev; + int rd; if (is_down != NULL) *is_down = 0; - for (i = 0; i < dcount; i++) - if (devs[i]->fd > fdmax) fdmax = devs[i]->fd; - - while (1) - { - struct input_event ev; - in_evdev_t *dev = NULL; - int ret, rd; - fd_set fdset; - - FD_ZERO(&fdset); - for (i = 0; i < dcount; i++) - FD_SET(devs[i]->fd, &fdset); - - ret = select(fdmax + 1, &fdset, NULL, NULL, timeout); - if (ret == -1) - { - perror("in_evdev: select failed"); - sleep(1); - return 0; - } - - if (ret == 0) - return 0; /* timeout */ - - for (i = 0; i < dcount; i++) - if (FD_ISSET(devs[i]->fd, &fdset)) - *which = i, dev = devs[i]; + rd = read(dev->fd, &ev, sizeof(ev)); + if (rd < (int) sizeof(ev)) { + perror("in_evdev: error reading"); + sleep(1); + return 0; + } - rd = read(dev->fd, &ev, sizeof(ev)); - if (rd < (int) sizeof(ev)) { - perror("in_evdev: error reading"); - sleep(1); + if (ev.type == EV_KEY) { + if (ev.value < 0 || ev.value > 1) return 0; - } - - if (ev.type == EV_KEY) { - if (ev.value < 0 || ev.value > 1) - continue; + if (is_down != NULL) + *is_down = ev.value; + return ev.code; + } + else if (ev.type == EV_ABS) + { + int down = 0; + if (dev->abs_lzone != 0 && ev.code == ABS_X) { + if (ev.value < dev->abs_lzone) { + down = 1; + dev->abs_lastx = KEY_LEFT; + } + else if (ev.value > dev->abs_rzone) { + down = 1; + dev->abs_lastx = KEY_RIGHT; + } if (is_down != NULL) - *is_down = ev.value; - return ev.code; + *is_down = down; + return dev->abs_lastx; } - else if (ev.type == EV_ABS) - { - int down = 0; - if (dev->abs_lzone != 0 && ev.code == ABS_X) { - if (ev.value < dev->abs_lzone) { - down = 1; - dev->abs_lastx = KEY_LEFT; - } - else if (ev.value > dev->abs_rzone) { - down = 1; - dev->abs_lastx = KEY_RIGHT; - } - if (is_down != NULL) - *is_down = down; - return dev->abs_lastx; + if (dev->abs_tzone != 0 && ev.code == ABS_Y) { + if (ev.value < dev->abs_tzone) { + down = 1; + dev->abs_lasty = KEY_UP; } - if (dev->abs_tzone != 0 && ev.code == ABS_Y) { - if (ev.value < dev->abs_tzone) { - down = 1; - dev->abs_lasty = KEY_UP; - } - else if (ev.value > dev->abs_bzone) { - down = 1; - dev->abs_lasty = KEY_DOWN; - } - if (is_down != NULL) - *is_down = down; - return dev->abs_lasty; + else if (ev.value > dev->abs_bzone) { + down = 1; + dev->abs_lasty = KEY_DOWN; } + if (is_down != NULL) + *is_down = down; + return dev->abs_lasty; } } + + return 0; } static int in_evdev_menu_translate(int keycode) @@ -502,6 +468,7 @@ void in_evdev_init(void *vdrv) drv->get_def_binds = in_evdev_get_def_binds; drv->clean_binds = in_evdev_clean_binds; drv->set_blocking = in_evdev_set_blocking; + drv->update_keycode = in_evdev_update_keycode; drv->menu_translate = in_evdev_menu_translate; drv->get_key_code = in_evdev_get_key_code; drv->get_key_name = in_evdev_get_key_name; diff --git a/platform/linux/in_evdev.h b/platform/linux/in_evdev.h index 4106c5f4..84392c66 100644 --- a/platform/linux/in_evdev.h +++ b/platform/linux/in_evdev.h @@ -1,5 +1,4 @@ -int in_evdev_update(void *drv_data, int *binds); -int in_evdev_update_keycode(void **data, int count, int *which, int *is_down, int timeout_ms); void in_evdev_init(void *vdrv); +int in_evdev_update(void *drv_data, int *binds); -- 2.39.5