X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?p=libpicofe.git;a=blobdiff_plain;f=input.c;h=d0e4a4e691668a2ccb9806be7499a666a0717a79;hp=8030e1f944dc9fa5572d571c3b6431b3ac71960c;hb=HEAD;hpb=afdbb7c87325a4a6280943564da2e9e19cefc55b diff --git a/input.c b/input.c index 8030e1f..4f91a55 100644 --- a/input.c +++ b/input.c @@ -43,6 +43,8 @@ static int in_have_async_devs = 0; static int in_probe_dev_id; static int menu_key_state = 0; static int menu_last_used_dev = 0; +static int menu_key_prev = 0; +static int menu_key_repeat = 0; #define DRV(id) in_drivers[id] @@ -50,25 +52,26 @@ static int menu_last_used_dev = 0; static int *in_alloc_binds(int drv_id, int key_count) { const struct in_default_bind *defbinds; - int *binds; + int *binds, *binds_d; int i; binds = calloc(key_count * IN_BINDTYPE_COUNT * 2, sizeof(binds[0])); if (binds == NULL) return NULL; + binds_d = binds + key_count * IN_BINDTYPE_COUNT; + + /* always have a copy of defbinds */ defbinds = DRV(drv_id).defbinds; if (defbinds != NULL) { for (i = 0; ; i++) { - if (defbinds[i].bit == 0 && defbinds[i].code == 0) + if (defbinds[i].code == 0 && defbinds[i].btype == 0 + && defbinds[i].bit == 0) break; - binds[IN_BIND_OFFS(defbinds[i].code, defbinds[i].btype)] = + + binds_d[IN_BIND_OFFS(defbinds[i].code, defbinds[i].btype)] |= 1 << defbinds[i].bit; } - - /* always have a copy of defbinds */ - memcpy(binds + key_count * IN_BINDTYPE_COUNT, binds, - sizeof(binds[0]) * key_count * IN_BINDTYPE_COUNT); } return binds; @@ -140,6 +143,9 @@ void in_register(const char *nname, int drv_fd_hnd, void *drv_data, return; } + memcpy(binds, binds + key_count * IN_BINDTYPE_COUNT, + sizeof(binds[0]) * key_count * IN_BINDTYPE_COUNT); + in_devices[i].name = tmp; in_devices[i].binds = binds; in_devices[i].key_count = key_count; @@ -246,7 +252,7 @@ void in_probe(void) for (i = 0; i < in_driver_count; i++) { in_probe_dev_id = i; - in_drivers[i].probe(); + in_drivers[i].probe(&DRV(i)); } /* get rid of devs without binds and probes */ @@ -427,53 +433,46 @@ finish: int in_menu_wait_any(char *charcode, int timeout_ms) { int keys_old = menu_key_state; + int ret; + int dev_id = 0; - while (1) - { - int code, is_down = 0, dev_id = 0; + menu_key_prev = menu_key_state; - code = in_update_keycode(&dev_id, &is_down, charcode, timeout_ms); - if (code < 0) - break; + in_update_keycode(&dev_id, NULL, charcode, timeout_ms); - if (keys_old != menu_key_state) { - menu_last_used_dev = dev_id; - break; - } - } + if (keys_old != menu_key_state) + menu_last_used_dev = dev_id; - return menu_key_state; + ret = menu_key_state; + if (ret == 0) + menu_key_prev = 0; + + return ret; } /* wait for menu input, do autorepeat */ int in_menu_wait(int interesting, char *charcode, int autorep_delay_ms) { - static int inp_prev = 0; - static int repeats = 0; - int ret, release = 0, wait = 450; + int ret, wait = 450; - if (repeats) + if (menu_key_repeat) wait = autorep_delay_ms; - ret = in_menu_wait_any(charcode, wait); - if (ret == inp_prev) - repeats++; - - while (!(ret & interesting)) { - ret = in_menu_wait_any(charcode, -1); - release = 1; - } - - if (release || ret != inp_prev) - repeats = 0; - - inp_prev = ret; + /* wait until either key repeat or a new key has been pressed */ +#ifdef SDL_REDRAW_EVT + interesting |= PBTN_RDRAW; +#endif + do { + ret = in_menu_wait_any(charcode, wait); + if (ret == 0 || ret != menu_key_prev) + menu_key_repeat = 0; + else + menu_key_repeat++; + wait = -1; + } while (!(ret & interesting)); /* we don't need diagonals in menus */ - if ((ret & PBTN_UP) && (ret & PBTN_LEFT)) ret &= ~PBTN_LEFT; - if ((ret & PBTN_UP) && (ret & PBTN_RIGHT)) ret &= ~PBTN_RIGHT; - if ((ret & PBTN_DOWN) && (ret & PBTN_LEFT)) ret &= ~PBTN_LEFT; - if ((ret & PBTN_DOWN) && (ret & PBTN_RIGHT)) ret &= ~PBTN_RIGHT; + if (ret & (PBTN_UP|PBTN_DOWN)) ret &= ~(PBTN_LEFT|PBTN_RIGHT); return ret; } @@ -490,6 +489,8 @@ const int *in_get_dev_def_binds(int dev_id) in_dev_t *dev = get_dev(dev_id); if (dev == NULL) return NULL; + if (dev->binds == NULL) + return NULL; return dev->binds + dev->key_count * IN_BINDTYPE_COUNT; } @@ -514,6 +515,9 @@ int in_get_config(int dev_id, int what, void *val) case IN_CFG_KEY_NAMES: return -1; /* not implemented */ default: + if (!dev->probed) + return -1; + return DRV(dev->drv_id).get_config(dev->drv_data, what, ival); } @@ -527,19 +531,22 @@ static int in_set_blocking(int is_blocking) /* 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); + if (!in_devices[i].probed) + continue; + + 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, NULL, 0); } while (ret >= 0); + menu_key_state = 0; + return 0; } @@ -769,7 +776,7 @@ int in_config_parse_dev(const char *name) } if (drv_id < 0) { - lprintf("input: missing driver for %s\n", name); + lprintf("input: missing driver for '%s'\n", name); return -1; } @@ -787,7 +794,8 @@ int in_config_parse_dev(const char *name) for (i = 0; i < IN_MAX_DEVS; i++) if (in_devices[i].name == NULL) break; if (i >= IN_MAX_DEVS) { - lprintf("input: too many devices, can't add %s\n", name); + lprintf("input: too many devices, can't add '%s'\n", + name); return -1; } } @@ -798,7 +806,8 @@ int in_config_parse_dev(const char *name) if (in_devices[i].name == NULL) return -1; - in_devices[i].key_names = DRV(drv_id).get_key_names(&in_devices[i].key_count); + in_devices[i].key_names = DRV(drv_id).get_key_names(&DRV(drv_id), + &in_devices[i].key_count); in_devices[i].drv_id = drv_id; if (i + 1 > in_dev_count) @@ -851,7 +860,8 @@ int in_config_bind_key(int dev_id, const char *key, int acts, int bind_type) } if (kc < 0 || kc >= dev->key_count) { - lprintf("input: bad key: %s\n", key); + lprintf("input: bad key: '%s' for device '%s'\n", + key, dev->name); return -1; } @@ -876,7 +886,7 @@ void in_clean_binds(void) int ret, count, *binds, *def_binds; in_dev_t *dev = &in_devices[i]; - if (dev->binds == NULL || dev->drv_data == NULL) + if (dev->binds == NULL || !dev->probed) continue; count = dev->key_count; @@ -901,8 +911,25 @@ void in_debug_dump(void) in_dev_t *d = &in_devices[i]; if (!d->probed && d->name == NULL && d->binds == NULL) continue; - lprintf("%d %3d %6c %5c %s\n", i, d->drv_id, d->probed ? 'y' : 'n', + lprintf("%d %3d %6c %5c %s\n", i, d->drv_id, + d->probed ? 'y' : 'n', d->binds ? 'y' : 'n', d->name); +#if 0 + if (d->binds) { + int kc, o, t, h; + for (kc = 0; kc < d->key_count; kc++) { + o = IN_BIND_OFFS(kc, 0); + for (t = h = 0; t < IN_BINDTYPE_COUNT; t++) + h |= d->binds[o + t]; + if (h == 0) + continue; + lprintf(" [%3d] =", kc); + for (t = 0; t < IN_BINDTYPE_COUNT; t++) + printf(" %x", d->binds[o + t]); + printf("\n"); + } + } +#endif } } @@ -922,7 +949,8 @@ static const char *in_def_get_key_name(int keycode) { return NULL; } if (d.f == NULL) d.f = in_def_##f /* to be called by drivers */ -int in_register_driver(const in_drv_t *drv, const struct in_default_bind *defbinds) +int in_register_driver(const in_drv_t *drv, + const struct in_default_bind *defbinds, const void *pdata) { int count_new = in_driver_count + 1; in_drv_t *new_drivers; @@ -944,7 +972,9 @@ int in_register_driver(const in_drv_t *drv, const struct in_default_bind *defbin CHECK_ADD_STUB(new_drivers[in_driver_count], menu_translate); CHECK_ADD_STUB(new_drivers[in_driver_count], get_key_code); CHECK_ADD_STUB(new_drivers[in_driver_count], get_key_name); - if (defbinds != NULL) + if (pdata) + new_drivers[in_driver_count].pdata = pdata; + if (defbinds) new_drivers[in_driver_count].defbinds = defbinds; in_drivers = new_drivers; in_driver_count = count_new;