+/*
+ * (C) GraÅžvydas "notaz" Ignotas, 2008-2010
+ *
+ * This work is licensed under the terms of any of these licenses
+ * (at your option):
+ * - GNU GPL, version 2 or later.
+ * - GNU LGPL, version 2.1 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
static in_drv_t in_drivers[IN_DRVID_COUNT];
static in_dev_t in_devices[IN_MAX_DEVS];
-static int in_dev_count = 0;
+static int in_dev_count = 0; /* probed + bind devices */
static int in_have_async_devs = 0;
static int menu_key_state = 0;
static int menu_last_used_dev = 0;
return binds;
}
-static void in_free(in_dev_t *dev)
+static void in_unprobe(in_dev_t *dev)
{
if (dev->probed)
DRV(dev->drv_id).free(dev->drv_data);
dev->probed = 0;
dev->drv_data = NULL;
+}
+
+static void in_free(in_dev_t *dev)
+{
+ in_unprobe(dev);
free(dev->name);
dev->name = NULL;
free(dev->binds);
int i;
in_have_async_devs = 0;
+ menu_key_state = 0;
+ menu_last_used_dev = 0;
+
for (i = 0; i < in_dev_count; i++)
- in_devices[i].probed = 0;
+ in_unprobe(&in_devices[i]);
for (i = 1; i < IN_DRVID_COUNT; i++)
in_drivers[i].probe();
if (result >= 0)
break;
+ if (result == -2) {
+ lprintf("input: \"%s\" errored out, removing.\n", in_devices[dev_id].name);
+ in_unprobe(&in_devices[dev_id]);
+ break;
+ }
+
if (timeout_ms >= 0) {
unsigned int ticks2 = plat_get_ticks_ms();
timeout_ms -= ticks2 - ticks;
return 0;
}
-void in_unbind_all(int dev_id, int act_mask, int bind_type)
+/*
+ * Unbind act_mask on binds with type bind_type
+ * - if dev_id_ < 0, affects all devices
+ * else only affects dev_id_
+ * - if act_mask == -1, unbind all keys
+ * else only actions in mask
+ */
+void in_unbind_all(int dev_id_, int act_mask, int bind_type)
{
+ int dev_id = 0, dev_last = IN_MAX_DEVS - 1;
int i, count;
in_dev_t *dev;
- if (dev_id < 0 || dev_id >= IN_MAX_DEVS || bind_type >= IN_BINDTYPE_COUNT)
+ if (dev_id_ >= 0)
+ dev_id = dev_last = dev_id_;
+
+ if (bind_type >= IN_BINDTYPE_COUNT)
return;
- dev = &in_devices[dev_id];
- count = dev->key_count;
+ for (; dev_id <= dev_last; dev_id++) {
+ dev = &in_devices[dev_id];
+ count = dev->key_count;
- if (dev->binds == NULL)
- return;
+ if (dev->binds == NULL)
+ continue;
- for (i = 0; i < count; i++)
- dev->binds[IN_BIND_OFFS(i, bind_type)] &= ~act_mask;
+ if (act_mask != -1) {
+ for (i = 0; i < count; i++)
+ dev->binds[IN_BIND_OFFS(i, bind_type)] &= ~act_mask;
+ }
+ else
+ memset(dev->binds, 0, sizeof(dev->binds[0]) * count * IN_BINDTYPE_COUNT);
+ }
}
/* returns device id, or -1 on error */
if (in_devices[i].name == NULL)
return -1;
- in_devices[i].key_count = DRV(drv_id).get_bind_count();
+ in_devices[i].key_names = DRV(drv_id).get_key_names(&in_devices[i].key_count);
in_devices[i].drv_id = drv_id;
if (i + 1 > in_dev_count)
return i;
}
-/*
- * To reduce size of game specific configs, default binds are not saved.
- * So we mark default binds in in_config_start(), override them in in_config_bind_key(),
- * and restore whatever default binds are left in in_config_end().
- */
-void in_config_start(void)
-{
- int i;
-
- /* mark all default binds, so they get overwritten by func below */
- for (i = 0; i < IN_MAX_DEVS; i++) {
- int n, count, *binds, *def_binds;
-
- binds = in_devices[i].binds;
- if (binds == NULL)
- continue;
-
- count = in_devices[i].key_count;
- def_binds = binds + count * IN_BINDTYPE_COUNT;
-
- for (n = 0; n < count * IN_BINDTYPE_COUNT; n++)
- if (binds[n] == def_binds[n])
- binds[n] = -1;
- }
-}
-
int in_config_bind_key(int dev_id, const char *key, int acts, int bind_type)
{
in_dev_t *dev;
dev->binds = in_alloc_binds(dev->drv_id, dev->key_count);
if (dev->binds == NULL)
return -1;
- in_config_start();
}
kc = -1;
return 0;
}
-void in_config_end(void)
+void in_clean_binds(void)
{
int i;
for (i = 0; i < IN_MAX_DEVS; i++) {
- int n, t, ret, count, *binds, *def_binds;
+ int ret, count, *binds, *def_binds;
in_dev_t *dev = &in_devices[i];
- if (dev->binds == NULL)
+ if (dev->binds == NULL || dev->drv_data == NULL)
continue;
count = dev->key_count;
binds = dev->binds;
def_binds = binds + count * IN_BINDTYPE_COUNT;
- for (n = 0; n < count; n++) {
- int is_default = 1;
- for (t = 0; t < IN_BINDTYPE_COUNT; t++)
- if (binds[IN_BIND_OFFS(n, t)] == -1)
- binds[IN_BIND_OFFS(n, t)] = 0;
- else
- is_default = 0;
-
- if (is_default)
- for (t = 0; t < IN_BINDTYPE_COUNT; t++)
- binds[IN_BIND_OFFS(n, t)] = def_binds[IN_BIND_OFFS(n, t)];
- }
-
- if (dev->drv_data == NULL)
- continue;
-
ret = DRV(dev->drv_id).clean_binds(dev->drv_data, binds, def_binds);
if (ret == 0) {
/* no useable binds */
static void in_def_probe(void) {}
static void in_def_free(void *drv_data) {}
-static int in_def_get_bind_count(void) { return 0; }
+static const char * const *
+ in_def_get_key_names(int *count) { return NULL; }
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 int in_def_get_config(void *drv_data, int what, int *val) { return -1; }
in_drivers[i].prefix = "none:";
in_drivers[i].probe = in_def_probe;
in_drivers[i].free = in_def_free;
- in_drivers[i].get_bind_count = in_def_get_bind_count;
+ in_drivers[i].get_key_names = in_def_get_key_names;
in_drivers[i].get_def_binds = in_def_get_def_binds;
in_drivers[i].clean_binds = in_def_clean_binds;
in_drivers[i].get_config = in_def_get_config;