X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?p=libpicofe.git;a=blobdiff_plain;f=input.c;h=d0e4a4e691668a2ccb9806be7499a666a0717a79;hp=783ed1e2be69fd4890a36de12f5f9d9d14b00701;hb=HEAD;hpb=9fec8a91c9b19856ac0b51de53b847b38ed8dc61 diff --git a/input.c b/input.c index 783ed1e..92b47a2 100644 --- a/input.c +++ b/input.c @@ -17,11 +17,6 @@ #include "plat.h" #include "lprintf.h" -#ifdef IN_VK -#error needs update: in_vk_init in_vk_update -#include "../win32/in_vk.h" -#endif - typedef struct { int drv_id; @@ -30,6 +25,7 @@ typedef struct char *name; int key_count; int *binds; /* total = key_count * bindtypes * 2 */ + int *kbd_binds; /* total = key_count */ const char * const *key_names; unsigned int probed:1; unsigned int does_combos:1; @@ -43,6 +39,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] @@ -63,7 +61,7 @@ static int *in_alloc_binds(int drv_id, int key_count) defbinds = DRV(drv_id).defbinds; if (defbinds != NULL) { for (i = 0; ; i++) { - if (defbinds[i].bit == 0 && defbinds[i].btype == 0 + if (defbinds[i].code == 0 && defbinds[i].btype == 0 && defbinds[i].bit == 0) break; @@ -75,6 +73,31 @@ static int *in_alloc_binds(int drv_id, int key_count) return binds; } +static int *in_alloc_kbd_binds(int drv_id, int key_count) +{ + const struct in_default_bind *defbinds; + int *binds; + int i; + + binds = calloc(key_count * 2, sizeof(binds[0])); + if (binds == NULL) + return NULL; + + /* always have a copy of defbinds */ + defbinds = DRV(drv_id).kbd_binds; + if (defbinds != NULL) { + for (i = 0; ; i++) { + if (defbinds[i].code == 0 && defbinds[i].btype == 0 + && defbinds[i].bit == 0) + break; + + binds[defbinds[i].code] = defbinds[i].bit; + } + } + + return binds; +} + static void in_unprobe(in_dev_t *dev) { if (dev->probed) @@ -97,7 +120,7 @@ static void in_free(in_dev_t *dev) void in_register(const char *nname, int drv_fd_hnd, void *drv_data, int key_count, const char * const *key_names, int combos) { - int i, ret, dupe_count = 0, *binds; + int i, ret, dupe_count = 0, *binds, *kbd_binds; char name[256], *name_end, *tmp; strncpy(name, nname, sizeof(name)); @@ -140,12 +163,18 @@ void in_register(const char *nname, int drv_fd_hnd, void *drv_data, free(tmp); return; } + kbd_binds = in_alloc_kbd_binds(in_probe_dev_id, key_count); + if (kbd_binds == NULL) { + free(tmp); + 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].kbd_binds = kbd_binds; in_devices[i].key_count = key_count; if (i + 1 > in_dev_count) in_dev_count = i + 1; @@ -290,6 +319,19 @@ int in_update(int *result) return ret; } +int in_update_kbd(int *result) +{ + int i, ret = 0; + + for (i = 0; i < in_dev_count; i++) { + in_dev_t *dev = &in_devices[i]; + if (dev->probed && dev->binds != NULL) + ret += DRV(dev->drv_id).update_kbd(dev->drv_data, dev->kbd_binds, result+ret); + } + + return ret; +} + static in_dev_t *get_dev(int dev_id) { if (dev_id < 0 || dev_id >= IN_MAX_DEVS) @@ -308,6 +350,16 @@ int in_update_analog(int dev_id, int axis_id, int *result) return DRV(dev->drv_id).update_analog(dev->drv_data, axis_id, result); } +int in_update_pointer(int dev_id, int id, int *result) +{ + in_dev_t *dev = get_dev(dev_id); + + if (dev == NULL || !dev->probed) + return -1; + + return DRV(dev->drv_id).update_pointer(dev->drv_data, id, result); +} + static int in_update_kc_async(int *dev_id_out, int *is_down_out, int timeout_ms) { int i, is_down, result; @@ -355,8 +407,11 @@ int in_update_keycode(int *dev_id_out, int *is_down_out, char *charcode, int tim if (in_have_async_devs) { result = in_update_kc_async(&dev_id, &is_down, timeout_ms); - if (result == -1) + if (result == -1) { + // no key up event for RDRAW, clear to avoid key repeat + menu_key_state &= ~PBTN_RDRAW; return -1; + } drv = &DRV(in_devices[dev_id].drv_id); goto finish; } @@ -432,55 +487,43 @@ 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; ret = menu_key_state; - menu_key_state &= ~PBTN_CHAR; + 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 */ + interesting |= PBTN_RDRAW; + 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; } @@ -492,6 +535,13 @@ const int *in_get_dev_binds(int dev_id) return dev ? dev->binds : NULL; } +const int *in_get_dev_kbd_binds(int dev_id) +{ + in_dev_t *dev = get_dev(dev_id); + + return dev ? dev->kbd_binds : NULL; +} + const int *in_get_dev_def_binds(int dev_id) { in_dev_t *dev = get_dev(dev_id); @@ -503,7 +553,18 @@ const int *in_get_dev_def_binds(int dev_id) return dev->binds + dev->key_count * IN_BINDTYPE_COUNT; } -int in_get_config(int dev_id, int what, void *val) +const int *in_get_dev_kbd_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->kbd_binds; +} + +int in_get_config(int dev_id, enum in_cfg_opt what, void *val) { int *ival = val; in_dev_t *dev; @@ -548,17 +609,17 @@ static int in_set_blocking(int 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; } -int in_set_config(int dev_id, int what, const void *val, int size) +int in_set_config(int dev_id, enum in_cfg_opt what, const void *val, size_t size) { const char * const *names; const int *ival = val; @@ -735,6 +796,30 @@ int in_bind_key(int dev_id, int keycode, int mask, int bind_type, int force_unbi return 0; } +int in_bind_kbd_key(int dev_id, int keycode, int kbd_key) +{ + int count; + in_dev_t *dev; + + dev = get_dev(dev_id); + if (dev == NULL) + return -1; + + count = dev->key_count; + + if (dev->kbd_binds == NULL) { + dev->kbd_binds = in_alloc_kbd_binds(dev->drv_id, count); + if (dev->kbd_binds == NULL) + return -1; + } + + if (keycode < 0 || keycode >= count) + return -1; + + dev->kbd_binds[keycode] = (kbd_key == -1 ? 0 : kbd_key); + return 0; +} + /* * Unbind act_mask on binds with type bind_type * - if dev_id_ < 0, affects all devices @@ -764,9 +849,11 @@ void in_unbind_all(int dev_id_, int act_mask, int bind_type) if (act_mask != -1) { for (i = 0; i < count; i++) dev->binds[IN_BIND_OFFS(i, bind_type)] &= ~act_mask; - } - else + } else { memset(dev->binds, 0, sizeof(dev->binds[0]) * count * IN_BINDTYPE_COUNT); + if (dev->kbd_binds) + memset(dev->kbd_binds, 0, sizeof(dev->kbd_binds[0]) * count); + } } } @@ -824,14 +911,9 @@ int in_config_parse_dev(const char *name) return i; } -int in_config_bind_key(int dev_id, const char *key, int acts, int bind_type) +static int parse_key(in_dev_t *dev, const char *key) { - in_dev_t *dev; - int i, offs, kc; - - dev = get_dev(dev_id); - if (dev == NULL || bind_type >= IN_BINDTYPE_COUNT) - return -1; + int kc, i; /* maybe a raw code? */ if (key[0] == '\\' && key[1] == 'x') { @@ -867,6 +949,20 @@ int in_config_bind_key(int dev_id, const char *key, int acts, int bind_type) } } + return kc; +} + +int in_config_bind_key(int dev_id, const char *key, int acts, int bind_type) +{ + in_dev_t *dev; + int i, offs, kc; + + dev = get_dev(dev_id); + if (dev == NULL || bind_type >= IN_BINDTYPE_COUNT) + return -1; + + kc = parse_key(dev, key); + if (kc < 0 || kc >= dev->key_count) { lprintf("input: bad key: '%s' for device '%s'\n", key, dev->name); @@ -886,6 +982,28 @@ int in_config_bind_key(int dev_id, const char *key, int acts, int bind_type) return 0; } +int in_config_bind_kbd_key(int dev_id, const char *key, int kbd_key) +{ + in_dev_t *dev; + int kc; + + dev = get_dev(dev_id); + if (dev == NULL) + return -1; + + kc = parse_key(dev, key); + + if (kc < 0 || kc >= dev->key_count) { + lprintf("input: bad key: '%s' for device '%s'\n", + key, dev->name); + return -1; + } + + dev->kbd_binds[kc] = kbd_key; + + return 0; +} + void in_clean_binds(void) { int i; @@ -945,9 +1063,10 @@ void in_debug_dump(void) static void in_def_free(void *drv_data) {} static int in_def_clean_binds(void *drv_data, int *b, int *db) { return 1; } -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_get_config(void *drv_data, enum in_cfg_opt what, int *val) { return -1; } +static int in_def_set_config(void *drv_data, enum in_cfg_opt what, int val) { return -1; } static int in_def_update_analog(void *drv_data, int axis_id, int *result) { return -1; } +static int in_def_update_pointer(void *drv_data, int id, int *result) { return -1; } static int in_def_update_keycode(void *drv_data, int *is_down) { return 0; } static int in_def_menu_translate(void *drv_data, int keycode, char *ccode) { return 0; } static int in_def_get_key_code(const char *key_name) { return -1; } @@ -958,7 +1077,9 @@ static const char *in_def_get_key_name(int keycode) { return NULL; } /* to be called by drivers */ int in_register_driver(const in_drv_t *drv, - const struct in_default_bind *defbinds, const void *pdata) + const struct in_default_bind *defbinds, + const struct in_default_bind *kbd_map, + const void *pdata) { int count_new = in_driver_count + 1; in_drv_t *new_drivers; @@ -976,6 +1097,7 @@ int in_register_driver(const in_drv_t *drv, CHECK_ADD_STUB(new_drivers[in_driver_count], get_config); CHECK_ADD_STUB(new_drivers[in_driver_count], set_config); CHECK_ADD_STUB(new_drivers[in_driver_count], update_analog); + CHECK_ADD_STUB(new_drivers[in_driver_count], update_pointer); CHECK_ADD_STUB(new_drivers[in_driver_count], update_keycode); CHECK_ADD_STUB(new_drivers[in_driver_count], menu_translate); CHECK_ADD_STUB(new_drivers[in_driver_count], get_key_code); @@ -984,6 +1106,8 @@ int in_register_driver(const in_drv_t *drv, new_drivers[in_driver_count].pdata = pdata; if (defbinds) new_drivers[in_driver_count].defbinds = defbinds; + if (kbd_map) + new_drivers[in_driver_count].kbd_binds = kbd_map; in_drivers = new_drivers; in_driver_count = count_new;