static int *in_alloc_binds(int drv_id, int key_count)
{
+ const struct in_default_bind *defbinds;
int *binds;
+ int i;
binds = calloc(key_count * IN_BINDTYPE_COUNT * 2, sizeof(binds[0]));
if (binds == NULL)
return NULL;
- DRV(drv_id).get_def_binds(binds + key_count * IN_BINDTYPE_COUNT);
- memcpy(binds, binds + key_count * IN_BINDTYPE_COUNT,
- sizeof(binds[0]) * key_count * IN_BINDTYPE_COUNT);
+ defbinds = DRV(drv_id).defbinds;
+ if (defbinds != NULL) {
+ for (i = 0; ; i++) {
+ if (defbinds[i].bit == 0 && defbinds[i].code == 0)
+ break;
+ binds[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;
}
return ret;
}
+static in_dev_t *get_dev(int dev_id)
+{
+ if (dev_id < 0 || dev_id >= IN_MAX_DEVS)
+ return NULL;
+
+ return &in_devices[dev_id];
+}
+
+int in_update_analog(int dev_id, int axis_id, int *result)
+{
+ in_dev_t *dev = get_dev(dev_id);
+
+ if (dev == NULL || !dev->probed)
+ return -1;
+
+ return DRV(dev->drv_id).update_analog(dev->drv_data, axis_id, result);
+}
+
static int in_update_kc_async(int *dev_id_out, int *is_down_out, int timeout_ms)
{
int i, is_down, result;
/*
* wait for a press, always return some keycode or -1 on timeout or error
*/
-int in_update_keycode(int *dev_id_out, int *is_down_out, int timeout_ms)
+int in_update_keycode(int *dev_id_out, int *is_down_out, char *charcode, int timeout_ms)
{
int result = -1, dev_id = 0, is_down, result_menu;
int fds_hnds[IN_MAX_DEVS];
finish:
/* keep track of menu key state, to allow mixing
* in_update_keycode() and in_menu_wait_any() calls */
- result_menu = drv->menu_translate(in_devices[dev_id].drv_data, result);
+ result_menu = drv->menu_translate(in_devices[dev_id].drv_data, result, charcode);
if (result_menu != 0) {
if (is_down)
menu_key_state |= result_menu;
}
/* same as above, only return bitfield of PBTN_* */
-int in_menu_wait_any(int timeout_ms)
+int in_menu_wait_any(char *charcode, int timeout_ms)
{
int keys_old = menu_key_state;
{
int code, is_down = 0, dev_id = 0;
- code = in_update_keycode(&dev_id, &is_down, timeout_ms);
+ code = in_update_keycode(&dev_id, &is_down, charcode, timeout_ms);
if (code < 0)
break;
}
/* wait for menu input, do autorepeat */
-int in_menu_wait(int interesting, int autorep_delay_ms)
+int in_menu_wait(int interesting, char *charcode, int autorep_delay_ms)
{
static int inp_prev = 0;
static int repeats = 0;
if (repeats)
wait = autorep_delay_ms;
- ret = in_menu_wait_any(wait);
+ ret = in_menu_wait_any(charcode, wait);
if (ret == inp_prev)
repeats++;
while (!(ret & interesting)) {
- ret = in_menu_wait_any(-1);
+ ret = in_menu_wait_any(charcode, -1);
release = 1;
}
const int *in_get_dev_binds(int dev_id)
{
- if (dev_id < 0 || dev_id >= IN_MAX_DEVS)
- return NULL;
+ in_dev_t *dev = get_dev(dev_id);
- return in_devices[dev_id].binds;
+ return dev ? dev->binds : NULL;
}
const int *in_get_dev_def_binds(int dev_id)
{
- if (dev_id < 0 || dev_id >= IN_MAX_DEVS)
+ in_dev_t *dev = get_dev(dev_id);
+ if (dev == NULL)
return NULL;
- return in_devices[dev_id].binds + in_devices[dev_id].key_count * IN_BINDTYPE_COUNT;
+ return dev->binds + dev->key_count * IN_BINDTYPE_COUNT;
}
int in_get_config(int dev_id, int what, void *val)
int *ival = val;
in_dev_t *dev;
- if (dev_id < 0 || dev_id >= IN_MAX_DEVS || val == NULL)
+ dev = get_dev(dev_id);
+ if (dev == NULL || val == NULL)
return -1;
- dev = &in_devices[dev_id];
switch (what) {
case IN_CFG_BIND_COUNT:
*ival = dev->key_count;
/* flush events */
do {
- ret = in_update_keycode(NULL, NULL, 0);
+ ret = in_update_keycode(NULL, NULL, NULL, 0);
} while (ret >= 0);
return 0;
int in_set_config(int dev_id, int what, const void *val, int size)
{
+ const char * const *names;
const int *ival = val;
in_dev_t *dev;
+ int count;
if (what == IN_CFG_BLOCKING)
return in_set_blocking(*ival);
- if (dev_id < 0 || dev_id >= IN_MAX_DEVS)
+ dev = get_dev(dev_id);
+ if (dev == NULL)
return -1;
- dev = &in_devices[dev_id];
- if (what == IN_CFG_KEY_NAMES) {
- const char * const *names = val;
- int count = size / sizeof(names[0]);
+ switch (what) {
+ case IN_CFG_KEY_NAMES:
+ names = val;
+ count = size / sizeof(names[0]);
if (count < dev->key_count) {
lprintf("input: set_key_names: not enough keys\n");
dev->key_names = names;
return 0;
+ case IN_CFG_DEFAULT_DEV:
+ /* just set last used dev, for now */
+ menu_last_used_dev = dev_id;
+ return 0;
+ default:
+ break;
}
- return DRV(dev->drv_id).set_config(dev->drv_data, what, *ival);
+ if (dev->probed)
+ return DRV(dev->drv_id).set_config(dev->drv_data, what, *ival);
+
+ return -1;
}
const char *in_get_dev_name(int dev_id, int must_be_active, int skip_pfix)
{
const char *name, *tmp;
+ in_dev_t *dev;
- if (dev_id < 0 || dev_id >= IN_MAX_DEVS)
+ dev = get_dev(dev_id);
+ if (dev == NULL)
return NULL;
- if (must_be_active && !in_devices[dev_id].probed)
+ if (must_be_active && !dev->probed)
return NULL;
- name = in_devices[dev_id].name;
+ name = dev->name;
if (name == NULL || !skip_pfix)
return name;
if (dev_id < 0) /* want last used dev? */
dev_id = menu_last_used_dev;
- if (dev_id < 0 || dev_id >= IN_MAX_DEVS)
+ dev = get_dev(dev_id);
+ if (dev == NULL)
return "Unkn0";
- dev = &in_devices[dev_id];
drv = &DRV(dev->drv_id);
if (keycode < 0) /* want name for menu key? */
- keycode = drv->menu_translate(dev->drv_data, keycode);
+ keycode = drv->menu_translate(dev->drv_data, keycode, NULL);
if (dev->key_names != NULL && 0 <= keycode && keycode < dev->key_count)
name = dev->key_names[keycode];
if (dev_id < 0) /* want last used dev? */
dev_id = menu_last_used_dev;
- if (dev_id < 0 || dev_id >= IN_MAX_DEVS)
+ dev = get_dev(dev_id);
+ if (dev == NULL)
return -1;
- dev = &in_devices[dev_id];
if (dev->key_names == NULL)
return -1;
int ret, count;
in_dev_t *dev;
- if (dev_id < 0 || dev_id >= IN_MAX_DEVS || bind_type >= IN_BINDTYPE_COUNT)
+ dev = get_dev(dev_id);
+ if (dev == NULL || bind_type >= IN_BINDTYPE_COUNT)
return -1;
- dev = &in_devices[dev_id];
count = dev->key_count;
if (dev->binds == NULL) {
in_dev_t *dev;
int i, offs, kc;
- if (dev_id < 0 || dev_id >= IN_MAX_DEVS || bind_type >= IN_BINDTYPE_COUNT)
+ dev = get_dev(dev_id);
+ if (dev == NULL || bind_type >= IN_BINDTYPE_COUNT)
return -1;
- dev = &in_devices[dev_id];
/* maybe a raw code? */
if (key[0] == '\\' && key[1] == 'x') {
/* stubs for drivers that choose not to implement something */
static void in_def_free(void *drv_data) {}
-static void in_def_get_def_binds(int *binds) {}
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_update_analog(void *drv_data, int axis_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) { 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; }
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)
+int in_register_driver(const in_drv_t *drv, const struct in_default_bind *defbinds)
{
int count_new = in_driver_count + 1;
in_drv_t *new_drivers;
memcpy(&new_drivers[in_driver_count], drv, sizeof(new_drivers[0]));
CHECK_ADD_STUB(new_drivers[in_driver_count], free);
- CHECK_ADD_STUB(new_drivers[in_driver_count], get_def_binds);
CHECK_ADD_STUB(new_drivers[in_driver_count], clean_binds);
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_keycode);
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)
+ new_drivers[in_driver_count].defbinds = defbinds;
in_drivers = new_drivers;
in_driver_count = count_new;