From: notaz Date: Fri, 17 Sep 2010 09:36:48 +0000 (+0000) Subject: input: rework abs handling, change API, allow custom key names X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?p=libpicofe.git;a=commitdiff_plain;h=e9b2926437ccf6b630cf79e00ed98f7934201c20 input: rework abs handling, change API, allow custom key names git-svn-id: file:///home/notaz/opt/svn/PicoDrive/platform@894 be3aeb3a-fb24-0410-a615-afba39da0efa --- diff --git a/common/input.c b/common/input.c index eda86d4..182e9fb 100644 --- a/common/input.c +++ b/common/input.c @@ -24,8 +24,9 @@ typedef struct char *name; int key_count; int *binds; /* total = key_count * bindtypes * 2 */ - int probed:1; - int does_combos:1; + const char * const *key_names; + unsigned int probed:1; + unsigned int does_combos:1; } in_dev_t; static in_drv_t in_drivers[IN_DRVID_COUNT]; @@ -68,7 +69,7 @@ static void in_free(in_dev_t *dev) /* to be called by drivers * async devices must set drv_fd_hnd to -1 */ void in_register(const char *nname, int drv_id, int drv_fd_hnd, void *drv_data, - int key_count, int combos) + int key_count, const char * const *key_names, int combos) { int i, ret, dupe_count = 0, *binds; char name[256], *name_end, *tmp; @@ -126,6 +127,7 @@ update: in_devices[i].does_combos = combos; in_devices[i].drv_id = drv_id; in_devices[i].drv_fd_hnd = drv_fd_hnd; + in_devices[i].key_names = key_names; in_devices[i].drv_data = drv_data; if (in_devices[i].binds != NULL) { @@ -236,6 +238,8 @@ void in_probe(void) if (in_have_async_devs) lprintf("input: async-only devices detected..\n"); + + in_debug_dump(); } /* async update */ @@ -270,26 +274,6 @@ int in_update(int *result) return ret; } -void in_set_blocking(int is_blocking) -{ - int i, ret; - - /* have_async_devs means we will have to do all reads async anyway.. */ - if (!in_have_async_devs) { - for (i = 0; i < in_dev_count; i++) { - if (in_devices[i].probed) - DRV(in_devices[i].drv_id).set_blocking(in_devices[i].drv_data, is_blocking); - } - } - - menu_key_state = 0; - - /* flush events */ - do { - ret = in_update_keycode(NULL, NULL, 0); - } while (ret >= 0); -} - static int in_update_kc_async(int *dev_id_out, int *is_down_out, int timeout_ms) { int i, is_down, result; @@ -391,7 +375,7 @@ int in_update_keycode(int *dev_id_out, int *is_down_out, int timeout_ms) finish: /* keep track of menu key state, to allow mixing * in_update_keycode() and in_menu_wait_any() calls */ - result_menu = drv->menu_translate(result); + result_menu = drv->menu_translate(in_devices[dev_id].drv_data, result); if (result_menu != 0) { if (is_down) menu_key_state |= result_menu; @@ -416,16 +400,13 @@ int in_menu_wait_any(int timeout_ms) int code, is_down = 0, dev_id = 0; code = in_update_keycode(&dev_id, &is_down, timeout_ms); - if (code >= 0) - code = DRV(in_devices[dev_id].drv_id).menu_translate(code); - - if (timeout_ms >= 0) - break; if (code < 0) - continue; - menu_last_used_dev = dev_id; - if (keys_old != menu_key_state) break; + + if (keys_old != menu_key_state) { + menu_last_used_dev = dev_id; + break; + } } return menu_key_state; @@ -480,21 +461,83 @@ const int *in_get_dev_def_binds(int dev_id) return in_devices[dev_id].binds + in_devices[dev_id].key_count * IN_BINDTYPE_COUNT; } -int in_get_dev_info(int dev_id, int what) +int in_get_config(int dev_id, int what, void *val) { - if (dev_id < 0 || dev_id >= IN_MAX_DEVS) - return 0; + int *ival = val; + in_dev_t *dev; + if (dev_id < 0 || dev_id >= IN_MAX_DEVS || val == NULL) + return -1; + + dev = &in_devices[dev_id]; switch (what) { - case IN_INFO_BIND_COUNT: - return in_devices[dev_id].key_count; - case IN_INFO_DOES_COMBOS: - return in_devices[dev_id].does_combos; + case IN_CFG_BIND_COUNT: + *ival = dev->key_count; + break; + case IN_CFG_DOES_COMBOS: + *ival = dev->does_combos; + break; + case IN_CFG_BLOCKING: + case IN_CFG_KEY_NAMES: + return -1; /* not implemented */ + default: + return DRV(dev->drv_id).get_config(dev->drv_data, what, ival); + } + + return 0; +} + +static int in_set_blocking(int is_blocking) +{ + int i, ret; + + /* have_async_devs means we will have to do all reads async anyway.. */ + if (!in_have_async_devs) { + for (i = 0; i < in_dev_count; i++) { + if (in_devices[i].probed) + DRV(in_devices[i].drv_id).set_config(in_devices[i].drv_data, + IN_CFG_BLOCKING, is_blocking); + } } + menu_key_state = 0; + + /* flush events */ + do { + ret = in_update_keycode(NULL, NULL, 0); + } while (ret >= 0); + return 0; } +int in_set_config(int dev_id, int what, const void *val, int size) +{ + const int *ival = val; + in_dev_t *dev; + + if (what == IN_CFG_BLOCKING) + return in_set_blocking(*ival); + + if (dev_id < 0 || dev_id >= IN_MAX_DEVS) + return -1; + + dev = &in_devices[dev_id]; + if (what == IN_CFG_KEY_NAMES) { + const char * const *names = val; + int count = size / sizeof(names[0]); + + if (count < dev->key_count) { + lprintf("input: set_key_names: not enough keys\n"); + return -1; + } + + dev->key_names = names; + return 0; + } + + return DRV(dev->drv_id).set_config(dev->drv_data, what, *ival); +} + const char *in_get_dev_name(int dev_id, int must_be_active, int skip_pfix) { const char *name, *tmp; @@ -517,11 +560,28 @@ const char *in_get_dev_name(int dev_id, int must_be_active, int skip_pfix) return name; } +int in_name_to_id(const char *dev_name) +{ + int i; + + for (i = 0; i < in_dev_count; i++) + if (strcmp(dev_name, in_devices[i].name) == 0) + break; + + if (i >= in_dev_count) { + lprintf("input: in_name_to_id: no such device: %s\n", dev_name); + return -1; + } + + return i; +} + /* never returns NULL */ const char *in_get_key_name(int dev_id, int keycode) { + const char *name = NULL; static char xname[16]; - const char *name; + in_dev_t *dev; if (dev_id < 0) /* want last used dev? */ dev_id = menu_last_used_dev; @@ -529,10 +589,16 @@ const char *in_get_key_name(int dev_id, int keycode) if (dev_id < 0 || dev_id >= IN_MAX_DEVS) return "Unkn0"; + dev = &in_devices[dev_id]; if (keycode < 0) /* want name for menu key? */ - keycode = DRV(in_devices[dev_id].drv_id).menu_translate(keycode); + keycode = DRV(dev->drv_id).menu_translate(dev->drv_data, keycode); + + if (dev->key_names != NULL && 0 <= keycode && keycode < dev->key_count) + name = dev->key_names[keycode]; + if (name != NULL) + return name; - name = DRV(in_devices[dev_id].drv_id).get_key_name(keycode); + name = DRV(dev->drv_id).get_key_name(keycode); if (name != NULL) return name; @@ -703,7 +769,19 @@ int in_config_bind_key(int dev_id, const char *key, int acts, int bind_type) in_config_start(); } - kc = DRV(dev->drv_id).get_key_code(key); + kc = -1; + if (dev->key_names != NULL) { + for (i = 0; i < dev->key_count; i++) { + const char *k = dev->key_names[i]; + if (k != NULL && strcasecmp(k, key) == 0) { + kc = i; + break; + } + } + } + + if (kc < 0) + kc = DRV(dev->drv_id).get_key_code(key); if (kc < 0 && strlen(key) == 1) { /* assume scancode */ kc = key[0]; @@ -789,10 +867,11 @@ static void in_def_free(void *drv_data) {} 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 *b, int *db) { return 0; } -static void in_def_set_blocking(void *data, int y) {} +static int in_def_get_config(void *drv_data, int what, int *val) { return -1; } +static int in_def_set_config(void *drv_data, int what, int val) { return -1; } 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 int in_def_menu_translate(void *drv_data, int keycode) { return keycode; } +static int in_def_get_key_code(const char *key_name) { return -1; } static const char *in_def_get_key_name(int keycode) { return NULL; } void in_init(void) @@ -810,7 +889,8 @@ void in_init(void) in_drivers[i].get_bind_count = in_def_get_bind_count; 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].get_config = in_def_get_config; + in_drivers[i].set_config = in_def_set_config; 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; diff --git a/common/input.h b/common/input.h index 06b3de5..8fbf6e7 100644 --- a/common/input.h +++ b/common/input.h @@ -55,8 +55,11 @@ enum { }; enum { - IN_INFO_BIND_COUNT = 0, - IN_INFO_DOES_COMBOS, + IN_CFG_BIND_COUNT = 0, + IN_CFG_DOES_COMBOS, + IN_CFG_BLOCKING, + IN_CFG_KEY_NAMES, + IN_CFG_ABS_DEAD_ZONE, /* dead zone for analog-digital mapping */ }; enum { @@ -76,9 +79,10 @@ typedef struct { int (*get_bind_count)(void); void (*get_def_binds)(int *binds); int (*clean_binds)(void *drv_data, int *binds, int *def_finds); - void (*set_blocking)(void *data, int y); + int (*get_config)(void *drv_data, int what, int *val); + int (*set_config)(void *drv_data, int what, int val); int (*update_keycode)(void *drv_data, int *is_down); - int (*menu_translate)(int keycode); + int (*menu_translate)(void *drv_data, int keycode); int (*get_key_code)(const char *key_name); const char * (*get_key_name)(int keycode); } in_drv_t; @@ -86,22 +90,23 @@ typedef struct { /* to be called by drivers */ void in_register(const char *nname, int drv_id, int drv_fd_hnd, void *drv_data, - int key_count, int combos); + int key_count, const char * const *key_names, int combos); void in_combos_find(const int *binds, int last_key, int *combo_keys, int *combo_acts); int in_combos_do(int keys, const int *binds, int last_key, int combo_keys, int combo_acts); void in_init(void); void in_probe(void); int in_update(int *result); -void in_set_blocking(int is_blocking); int in_update_keycode(int *dev_id, int *is_down, int timeout_ms); int in_menu_wait_any(int timeout_ms); int in_menu_wait(int interesting, int autorep_delay_ms); -int in_get_dev_info(int dev_id, int what); void in_config_start(void); int in_config_parse_dev(const char *dev_name); int in_config_bind_key(int dev_id, const char *key, int binds, int bind_type); void in_config_end(void); +int in_get_config(int dev_id, int what, void *val); +int in_set_config(int dev_id, int what, const void *val, int size); +int in_name_to_id(const char *dev_name); int in_bind_key(int dev_id, int keycode, int mask, int bind_type, int force_unbind); void in_unbind_all(int dev_id, int act_mask, int bind_type); void in_debug_dump(void); @@ -110,3 +115,8 @@ const int *in_get_dev_binds(int dev_id); const int *in_get_dev_def_binds(int dev_id); const char *in_get_dev_name(int dev_id, int must_be_active, int skip_pfix); const char *in_get_key_name(int dev_id, int keycode); + +#define in_set_config_int(dev_id, what, v) { \ + int val_ = v; \ + in_set_config(dev_id, what, &val_, sizeof(val_)); \ +} diff --git a/gp2x/in_gp2x.c b/gp2x/in_gp2x.c index 9894669..01352c5 100644 --- a/gp2x/in_gp2x.c +++ b/gp2x/in_gp2x.c @@ -29,8 +29,8 @@ enum { BTN_UP = 0, BTN_LEFT = 2, BTN_DOWN = 4, BTN_RIGHT = 6, static const char * const in_gp2x_prefix = IN_PREFIX; static const char *in_gp2x_keys[IN_GP2X_NBUTTONS] = { [0 ... IN_GP2X_NBUTTONS-1] = NULL, - [BTN_UP] = "UP", [BTN_LEFT] = "LEFT", [BTN_DOWN] = "DOWN", [BTN_RIGHT] = "RIGHT", - [BTN_START] = "START", [BTN_SELECT] = "SELECT", [BTN_L] = "L", [BTN_R] = "R", + [BTN_UP] = "Up", [BTN_LEFT] = "Left", [BTN_DOWN] = "Down", [BTN_RIGHT] = "Right", + [BTN_START] = "Start", [BTN_SELECT] = "Select", [BTN_L] = "L", [BTN_R] = "R", [BTN_A] = "A", [BTN_B] = "B", [BTN_X] = "X", [BTN_Y] = "Y", [BTN_VOL_DOWN]= "VOL DOWN", [BTN_VOL_UP] = "VOL UP", [BTN_PUSH] = "PUSH" @@ -81,7 +81,7 @@ static int in_gp2x_get_wiz_bits(void) #ifdef FAKE_IN_GP2X volatile unsigned short *gp2x_memregs; -gp2x_soc_t soc_detect(void) { return -1; } +int gp2x_dev_id = -1; static int in_gp2x_get_fake_bits(void) { @@ -105,6 +105,7 @@ static void in_gp2x_probe(void) } in_gp2x_get_bits = in_gp2x_get_wiz_bits; break; + // we'll use evdev for Caanoo default: #ifdef FAKE_IN_GP2X in_gp2x_get_bits = in_gp2x_get_fake_bits; @@ -114,7 +115,7 @@ static void in_gp2x_probe(void) } in_register(IN_PREFIX "GP2X pad", IN_DRVID_GP2X, -1, (void *)1, - IN_GP2X_NBUTTONS, 1); + IN_GP2X_NBUTTONS, in_gp2x_keys, 1); } static void in_gp2x_free(void *drv_data) @@ -197,7 +198,7 @@ static const struct { #define KEY_PBTN_MAP_SIZE (sizeof(key_pbtn_map) / sizeof(key_pbtn_map[0])) -static int in_gp2x_menu_translate(int keycode) +static int in_gp2x_menu_translate(void *drv_data, int keycode) { int i; if (keycode < 0) @@ -218,30 +219,6 @@ static int in_gp2x_menu_translate(int keycode) return 0; } -static int in_gp2x_get_key_code(const char *key_name) -{ - int i; - - for (i = 0; i < IN_GP2X_NBUTTONS; i++) { - const char *k = in_gp2x_keys[i]; - if (k != NULL && strcasecmp(k, key_name) == 0) - return i; - } - - return -1; -} - -static const char *in_gp2x_get_key_name(int keycode) -{ - const char *name = NULL; - if (keycode >= 0 && keycode < IN_GP2X_NBUTTONS) - name = in_gp2x_keys[keycode]; - if (name == NULL) - name = "Unkn"; - - return name; -} - static const struct { short code; char btype; @@ -330,8 +307,6 @@ void in_gp2x_init(void *vdrv) drv->get_def_binds = in_gp2x_get_def_binds; drv->clean_binds = in_gp2x_clean_binds; drv->menu_translate = in_gp2x_menu_translate; - drv->get_key_code = in_gp2x_get_key_code; - drv->get_key_name = in_gp2x_get_key_name; drv->update_keycode = in_gp2x_update_keycode; } diff --git a/linux/in_evdev.c b/linux/in_evdev.c index 8a00296..edfa6ef 100644 --- a/linux/in_evdev.c +++ b/linux/in_evdev.c @@ -15,12 +15,15 @@ typedef struct { int fd; int *kbits; + int abs_min_x; + int abs_max_x; + int abs_min_y; + int abs_max_y; int abs_lzone; - int abs_rzone; - int abs_tzone; - int abs_bzone; int abs_lastx; int abs_lasty; + int kc_first; + int kc_last; } in_evdev_t; #ifndef KEY_CNT @@ -138,8 +141,8 @@ static void in_evdev_probe(void) for (i = 0;; i++) { int support = 0, count = 0; + int u, ret, fd, kc_first, kc_last; in_evdev_t *dev; - int u, ret, fd; char name[64]; snprintf(name, sizeof(name), "/dev/input/event%d", i); @@ -167,10 +170,17 @@ static void in_evdev_probe(void) } /* check for interesting keys */ + kc_first = KEY_MAX; + kc_last = 0; for (u = 0; u < KEY_CNT; u++) { - if (KEYBITS_BIT(u) && u != KEY_POWER && - u != KEY_SLEEP && u != BTN_TOUCH) - count++; + if (KEYBITS_BIT(u)) { + if (u < kc_first) + kc_first = u; + if (u > kc_last) + kc_last = u; + if (u != KEY_POWER && u != KEY_SLEEP && u != BTN_TOUCH) + count++; + } } if (count == 0) @@ -202,26 +212,29 @@ static void in_evdev_probe(void) if (ret == -1) goto no_abs; dist = ainfo.maximum - ainfo.minimum; - dev->abs_lzone = ainfo.minimum + dist / 4; - dev->abs_rzone = ainfo.maximum - dist / 4; + dev->abs_lzone = dist / 4; + dev->abs_min_x = ainfo.minimum; + dev->abs_max_x = ainfo.maximum; } if (absbits[0] & (1 << ABS_Y)) { ret = ioctl(fd, EVIOCGABS(ABS_Y), &ainfo); if (ret == -1) goto no_abs; dist = ainfo.maximum - ainfo.minimum; - dev->abs_tzone = ainfo.minimum + dist / 4; - dev->abs_bzone = ainfo.maximum - dist / 4; + dev->abs_min_y = ainfo.minimum; + dev->abs_max_y = ainfo.maximum; } } no_abs: dev->fd = fd; + dev->kc_first = kc_first; + dev->kc_last = kc_last; strcpy(name, in_evdev_prefix); 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, fd, dev, KEY_CNT, 0); + in_register(name, IN_DRVID_EVDEV, fd, dev, KEY_CNT, in_evdev_keys, 0); continue; skip: @@ -259,7 +272,7 @@ int in_evdev_update(void *drv_data, const int *binds, int *result) int keybits_[KEY_CNT / sizeof(int)]; int *keybits = keybits_; in_evdev_t *dev = drv_data; - int rd, ret, u; + int rd, ret, u, lzone; if (dev->kbits == NULL) { ret = ioctl(dev->fd, EVIOCGKEY(sizeof(keybits_)), keybits_); @@ -288,40 +301,40 @@ int in_evdev_update(void *drv_data, const int *binds, int *result) } } - for (u = 0; u < KEY_CNT; u++) { + for (u = dev->kc_first; u <= dev->kc_last; u++) { if (KEYBITS_BIT(u)) or_binds(binds, u, result); } /* map X and Y absolute to UDLR */ - if (dev->abs_lzone != 0) { + lzone = dev->abs_lzone; + if (lzone != 0) { ret = ioctl(dev->fd, EVIOCGABS(ABS_X), &ainfo); if (ret != -1) { - if (ainfo.value < dev->abs_lzone) or_binds(binds, KEY_LEFT, result); - if (ainfo.value > dev->abs_rzone) or_binds(binds, KEY_RIGHT, result); + if (ainfo.value < dev->abs_min_x + lzone) or_binds(binds, KEY_LEFT, result); + if (ainfo.value > dev->abs_max_x - lzone) or_binds(binds, KEY_RIGHT, result); } } - if (dev->abs_tzone != 0) { + if (lzone != 0) { ret = ioctl(dev->fd, EVIOCGABS(ABS_Y), &ainfo); if (ret != -1) { - if (ainfo.value < dev->abs_tzone) or_binds(binds, KEY_UP, result); - if (ainfo.value > dev->abs_bzone) or_binds(binds, KEY_DOWN, result); + if (ainfo.value < dev->abs_min_y + lzone) or_binds(binds, KEY_UP, result); + if (ainfo.value > dev->abs_max_y - lzone) or_binds(binds, KEY_DOWN, result); } } return 0; } -static void in_evdev_set_blocking(void *drv_data, int y) +static int in_evdev_set_blocking(in_evdev_t *dev, int y) { - in_evdev_t *dev = drv_data; long flags; int ret; flags = (long)fcntl(dev->fd, F_GETFL); if ((int)flags == -1) { perror("in_evdev: F_GETFL fcntl failed"); - return; + return -1; } if (flags & O_NONBLOCK) { @@ -338,67 +351,105 @@ static void in_evdev_set_blocking(void *drv_data, int y) else flags |= O_NONBLOCK; ret = fcntl(dev->fd, F_SETFL, flags); - if (ret == -1) + if (ret == -1) { perror("in_evdev: F_SETFL fcntl failed"); + return -1; + } + + return 0; +} + +static int in_evdev_set_config(void *drv_data, int what, int val) +{ + in_evdev_t *dev = drv_data; + int tmp; + + switch (what) { + case IN_CFG_BLOCKING: + return in_evdev_set_blocking(dev, val); + case IN_CFG_ABS_DEAD_ZONE: + if (val < 1 || val > 99 || dev->abs_lzone == 0) + return -1; + /* XXX: based on X axis only, for now.. */ + tmp = (dev->abs_max_x - dev->abs_min_x) / 2; + dev->abs_lzone = tmp - tmp * val / 100; + if (dev->abs_lzone < 1) + dev->abs_lzone = 1; + else if (dev->abs_lzone >= tmp) + dev->abs_lzone = tmp - 1; + break; + default: + return -1; + } + + return 0; } static int in_evdev_update_keycode(void *data, int *is_down) { + int ret_kc = -1, ret_down = 0; in_evdev_t *dev = data; struct input_event ev; int rd; - if (is_down != NULL) - *is_down = 0; - rd = read(dev->fd, &ev, sizeof(ev)); if (rd < (int) sizeof(ev)) { if (errno != EAGAIN) { perror("in_evdev: error reading"); sleep(1); } - return -1; + goto out; } if (ev.type == EV_KEY) { if (ev.value < 0 || ev.value > 1) - return -1; - if (is_down != NULL) - *is_down = ev.value; - return ev.code; + goto out; + ret_kc = ev.code; + ret_down = ev.value; + goto out; } 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; + int lzone = dev->abs_lzone, down = 0, *last; + + // map absolute to up/down/left/right + if (lzone != 0 && ev.code == ABS_X) { + if (ev.value < dev->abs_min_x + lzone) + down = KEY_LEFT; + else if (ev.value > dev->abs_max_x - lzone) + down = KEY_RIGHT; + last = &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; - } - 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 (lzone != 0 && ev.code == ABS_Y) { + if (ev.value < dev->abs_min_y + lzone) + down = KEY_UP; + else if (ev.value > dev->abs_max_y - lzone) + down = KEY_DOWN; + last = &dev->abs_lasty; + } + else + goto out; + + if (down == *last) + goto out; + + if (down == 0 || *last != 0) { + /* key up or direction change, return up event for old key */ + ret_kc = *last; + ret_down = 0; + *last = 0; + goto out; } + ret_kc = *last = down; + ret_down = 1; + goto out; } - return -1; +out: + if (is_down != NULL) + *is_down = ret_down; + + return ret_kc; } static const struct { @@ -410,36 +461,51 @@ static const struct { { KEY_DOWN, PBTN_DOWN }, { KEY_LEFT, PBTN_LEFT }, { KEY_RIGHT, PBTN_RIGHT }, - { KEY_ENTER, PBTN_MOK }, + /* XXX: maybe better set this from it's plat code somehow */ + /* Pandora */ { KEY_END, PBTN_MOK }, - { BTN_TRIGGER, PBTN_MOK }, - { KEY_ESC, PBTN_MBACK }, { KEY_PAGEDOWN, PBTN_MBACK }, - { BTN_THUMB, PBTN_MBACK }, - { KEY_A, PBTN_MA2 }, { KEY_HOME, PBTN_MA2 }, - { KEY_S, PBTN_MA3 }, { KEY_PAGEUP, PBTN_MA3 }, - { KEY_BACKSLASH, PBTN_MENU }, { KEY_LEFTCTRL, PBTN_MENU }, { KEY_RIGHTSHIFT, PBTN_L }, - { KEY_LEFTBRACE, PBTN_L }, { KEY_RIGHTCTRL, PBTN_R }, + /* Caanoo */ + { BTN_THUMB2, PBTN_MOK }, + { BTN_THUMB, PBTN_MBACK }, + { BTN_TRIGGER, PBTN_MA2 }, + { BTN_TOP, PBTN_MA3 }, + { BTN_BASE, PBTN_MENU }, + { BTN_TOP2, PBTN_L }, + { BTN_PINKIE, PBTN_R }, + /* "normal" keyboards */ + { KEY_ENTER, PBTN_MOK }, + { KEY_ESC, PBTN_MBACK }, + { KEY_A, PBTN_MA2 }, + { KEY_S, PBTN_MA3 }, + { KEY_BACKSLASH, PBTN_MENU }, + { KEY_LEFTBRACE, PBTN_L }, { KEY_RIGHTBRACE, PBTN_R }, }; #define KEY_PBTN_MAP_SIZE (sizeof(key_pbtn_map) / sizeof(key_pbtn_map[0])) -static int in_evdev_menu_translate(int keycode) +static int in_evdev_menu_translate(void *drv_data, int keycode) { + in_evdev_t *dev = drv_data; int i; + if (keycode < 0) { /* menu -> kc */ keycode = -keycode; for (i = 0; i < KEY_PBTN_MAP_SIZE; i++) - if (key_pbtn_map[i].pbtn == keycode) - return key_pbtn_map[i].key; + if (key_pbtn_map[i].pbtn == keycode) { + int k = key_pbtn_map[i].key; + /* should really check EVIOCGBIT, but this is enough for now */ + if (dev->kc_first <= k && k <= dev->kc_last) + return k; + } } else { @@ -451,30 +517,6 @@ static int in_evdev_menu_translate(int keycode) return 0; } -static int in_evdev_get_key_code(const char *key_name) -{ - int i; - - for (i = 0; i < KEY_CNT; i++) { - const char *k = in_evdev_keys[i]; - if (k != NULL && strcasecmp(k, key_name) == 0) - return i; - } - - return -1; -} - -static const char *in_evdev_get_key_name(int keycode) -{ - const char *name = NULL; - if (keycode >= 0 && keycode <= KEY_MAX) - name = in_evdev_keys[keycode]; - if (name == NULL) - name = "Unkn"; - - return name; -} - static const struct { short code; char btype; @@ -487,16 +529,26 @@ static const struct { { KEY_LEFT, IN_BINDTYPE_PLAYER12, 2 }, { KEY_RIGHT, IN_BINDTYPE_PLAYER12, 3 }, { KEY_S, IN_BINDTYPE_PLAYER12, 4 }, /* B */ - { KEY_PAGEDOWN, IN_BINDTYPE_PLAYER12, 4 }, { KEY_D, IN_BINDTYPE_PLAYER12, 5 }, /* C */ - { KEY_END, IN_BINDTYPE_PLAYER12, 5 }, { KEY_A, IN_BINDTYPE_PLAYER12, 6 }, /* A */ - { KEY_HOME, IN_BINDTYPE_PLAYER12, 6 }, { KEY_ENTER, IN_BINDTYPE_PLAYER12, 7 }, + { KEY_BACKSLASH, IN_BINDTYPE_EMU, PEVB_MENU }, + /* Pandora */ + { KEY_PAGEDOWN, IN_BINDTYPE_PLAYER12, 4 }, + { KEY_END, IN_BINDTYPE_PLAYER12, 5 }, + { KEY_HOME, IN_BINDTYPE_PLAYER12, 6 }, { KEY_LEFTALT, IN_BINDTYPE_PLAYER12, 7 }, { KEY_RIGHTSHIFT,IN_BINDTYPE_EMU, PEVB_STATE_SAVE }, { KEY_RIGHTCTRL, IN_BINDTYPE_EMU, PEVB_STATE_LOAD }, { KEY_LEFTCTRL, IN_BINDTYPE_EMU, PEVB_MENU }, + /* Caanoo */ + { BTN_THUMB, IN_BINDTYPE_PLAYER12, 4 }, /* B */ + { BTN_THUMB2, IN_BINDTYPE_PLAYER12, 5 }, /* C */ + { BTN_TRIGGER, IN_BINDTYPE_PLAYER12, 6 }, /* A */ + { BTN_BASE3, IN_BINDTYPE_PLAYER12, 7 }, + { BTN_TOP2, IN_BINDTYPE_EMU, PEVB_STATE_SAVE }, + { BTN_PINKIE, IN_BINDTYPE_EMU, PEVB_STATE_LOAD }, + { BTN_BASE, IN_BINDTYPE_EMU, PEVB_MENU }, }; #define DEF_BIND_COUNT (sizeof(in_evdev_def_binds) / sizeof(in_evdev_def_binds[0])) @@ -527,7 +579,7 @@ static int in_evdev_clean_binds(void *drv_data, int *binds, int *def_binds) KEYBITS_BIT_SET(KEY_LEFT); KEYBITS_BIT_SET(KEY_RIGHT); } - if (dev->abs_tzone != 0) { + if (dev->abs_lzone != 0) { KEYBITS_BIT_SET(KEY_UP); KEYBITS_BIT_SET(KEY_DOWN); } @@ -555,10 +607,8 @@ void in_evdev_init(void *vdrv) drv->get_bind_count = in_evdev_get_bind_count; drv->get_def_binds = in_evdev_get_def_binds; drv->clean_binds = in_evdev_clean_binds; - drv->set_blocking = in_evdev_set_blocking; + drv->set_config = in_evdev_set_config; 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/win32/in_vk.c b/win32/in_vk.c index 59538a7..44e1fde 100644 --- a/win32/in_vk.c +++ b/win32/in_vk.c @@ -65,7 +65,7 @@ static int in_vk_keys_down[4]; static void in_vk_probe(void) { memset(in_vk_keys_down, 0, sizeof(in_vk_keys_down)); - in_register(IN_VK_PREFIX "vk", IN_DRVID_VK, -1, (void *)1, IN_VK_NKEYS, 0); + in_register(IN_VK_PREFIX "vk", IN_DRVID_VK, -1, (void *)1, IN_VK_NKEYS, NULL, 0); } static int in_vk_get_bind_count(void) @@ -145,7 +145,7 @@ static const struct { #define KEY_PBTN_MAP_SIZE (sizeof(key_pbtn_map) / sizeof(key_pbtn_map[0])) -static int in_vk_menu_translate(int keycode) +static int in_vk_menu_translate(void *drv_data, int keycode) { int i; if (keycode < 0)