X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?p=libpicofe.git;a=blobdiff_plain;f=input.c;h=d0e4a4e691668a2ccb9806be7499a666a0717a79;hp=b2168fcb1c7a4d525a424bf197da8e4fdec843d1;hb=HEAD;hpb=1dd8f2036e7da6fc2e28863c9f0be589572a71da diff --git a/input.c b/input.c index b2168fc..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; @@ -44,7 +40,6 @@ 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_mask = 0; static int menu_key_repeat = 0; #define DRV(id) in_drivers[id] @@ -78,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) @@ -100,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)); @@ -143,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; @@ -293,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) @@ -311,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; @@ -358,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; } @@ -446,9 +498,7 @@ int in_menu_wait_any(char *charcode, int timeout_ms) ret = menu_key_state; if (ret == 0) - menu_key_mask = menu_key_prev = 0; - else if (ret != menu_key_prev) - menu_key_mask = menu_key_prev; + menu_key_prev = 0; return ret; } @@ -462,9 +512,7 @@ int in_menu_wait(int interesting, char *charcode, int autorep_delay_ms) wait = autorep_delay_ms; /* 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) @@ -472,9 +520,6 @@ int in_menu_wait(int interesting, char *charcode, int autorep_delay_ms) else menu_key_repeat++; wait = -1; - /* mask away all old keys if an additional new key is pressed */ - /* XXX what if old and new keys share bits (PBTN_CHAR)? */ - ret &= ~menu_key_mask; } while (!(ret & interesting)); /* we don't need diagonals in menus */ @@ -490,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); @@ -501,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; @@ -556,7 +619,7 @@ static int in_set_blocking(int is_blocking) 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; @@ -733,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 @@ -762,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); + } } } @@ -822,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') { @@ -865,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); @@ -884,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; @@ -943,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; } @@ -956,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; @@ -974,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); @@ -982,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;