/*
- * (C) Gražvydas "notaz" Ignotas, 2008-2010
+ * (C) Gražvydas "notaz" Ignotas, 2008-2011
*
* This work is licensed under the terms of any of these licenses
* (at your option):
#include "plat.h"
#include "lprintf.h"
-#ifdef IN_EVDEV
-#include "../linux/in_evdev.h"
-#endif
#ifdef IN_GP2X
+#error needs update: in_gp2x_init in_gp2x_update
#include "../gp2x/in_gp2x.h"
#endif
#ifdef IN_VK
+#error needs update: in_vk_init in_vk_update
#include "../win32/in_vk.h"
#endif
unsigned int does_combos:1;
} in_dev_t;
-static in_drv_t in_drivers[IN_DRVID_COUNT];
+static in_drv_t *in_drivers;
static in_dev_t in_devices[IN_MAX_DEVS];
+static int in_driver_count = 0;
static int in_dev_count = 0; /* probed + bind devices */
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;
-#define DRV(id) in_drivers[(unsigned)(id) < IN_DRVID_COUNT ? (id) : 0]
+#define DRV(id) in_drivers[id]
static int *in_alloc_binds(int drv_id, int key_count)
/* to be called by drivers
* async devices must set drv_fd_hnd to -1 */
-void in_register(const char *nname, int drv_id, int drv_fd_hnd, void *drv_data,
+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;
if (tmp == NULL)
return;
- binds = in_alloc_binds(drv_id, key_count);
+ binds = in_alloc_binds(in_probe_dev_id, key_count);
if (binds == NULL) {
free(tmp);
return;
update:
in_devices[i].probed = 1;
in_devices[i].does_combos = combos;
- in_devices[i].drv_id = drv_id;
+ in_devices[i].drv_id = in_probe_dev_id;
in_devices[i].drv_fd_hnd = drv_fd_hnd;
in_devices[i].key_names = key_names;
in_devices[i].drv_data = drv_data;
if (in_devices[i].binds != NULL) {
- ret = DRV(drv_id).clean_binds(drv_data, in_devices[i].binds,
+ ret = DRV(in_probe_dev_id).clean_binds(drv_data, in_devices[i].binds,
in_devices[i].binds + key_count * IN_BINDTYPE_COUNT);
if (ret == 0) {
/* no useable binds */
for (i = 0; i < in_dev_count; i++)
in_unprobe(&in_devices[i]);
- for (i = 1; i < IN_DRVID_COUNT; i++)
+ for (i = 0; i < in_driver_count; i++) {
+ in_probe_dev_id = i;
in_drivers[i].probe();
+ }
/* get rid of devs without binds and probes */
for (i = 0; i < in_dev_count; i++) {
for (i = 0; i < in_dev_count; i++) {
in_dev_t *dev = &in_devices[i];
- if (dev->probed && dev->binds != NULL) {
- // FIXME: this is stupid, make it indirect
- switch (dev->drv_id) {
-#ifdef IN_EVDEV
- case IN_DRVID_EVDEV:
- ret |= in_evdev_update(dev->drv_data, dev->binds, result);
- break;
-#endif
-#ifdef IN_GP2X
- case IN_DRVID_GP2X:
- ret |= in_gp2x_update(dev->drv_data, dev->binds, result);
- break;
-#endif
-#ifdef IN_VK
- case IN_DRVID_VK:
- ret |= in_vk_update(dev->drv_data, dev->binds, result);
- break;
-#endif
- }
- }
+ if (dev->probed && dev->binds != NULL)
+ ret |= DRV(dev->drv_id).update(dev->drv_data, dev->binds, result);
}
return ret;
{
const char *name = NULL;
static char xname[16];
+ in_drv_t *drv;
in_dev_t *dev;
if (dev_id < 0) /* want last used dev? */
return "Unkn0";
dev = &in_devices[dev_id];
+ drv = &DRV(dev->drv_id);
if (keycode < 0) /* want name for menu key? */
- keycode = DRV(dev->drv_id).menu_translate(dev->drv_data, keycode);
+ keycode = drv->menu_translate(dev->drv_data, keycode);
if (dev->key_names != NULL && 0 <= keycode && keycode < dev->key_count)
name = dev->key_names[keycode];
if (name != NULL)
return name;
- name = DRV(dev->drv_id).get_key_name(keycode);
+ if (drv->get_key_name != NULL)
+ name = drv->get_key_name(keycode);
if (name != NULL)
return name;
{
int drv_id = -1, i;
- for (i = 0; i < IN_DRVID_COUNT; i++) {
+ for (i = 0; i < in_driver_count; i++) {
int len = strlen(in_drivers[i].prefix);
if (strncmp(name, in_drivers[i].prefix, len) == 0) {
drv_id = i;
}
}
-/* handlers for unknown/not_preset drivers */
+/* stubs for drivers that choose not to implement something */
-static void in_def_probe(void) {}
static void in_def_free(void *drv_data) {}
-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_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_keycode(void *drv_data, int *is_down) { return 0; }
-static int in_def_menu_translate(void *drv_data, int keycode) { return keycode; }
+static int in_def_menu_translate(void *drv_data, int keycode) { 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; }
-void in_init(void)
-{
- int i;
+#define CHECK_ADD_STUB(d, f) \
+ if (d.f == NULL) d.f = in_def_##f
- memset(in_drivers, 0, sizeof(in_drivers));
- memset(in_devices, 0, sizeof(in_devices));
- in_dev_count = 0;
+/* to be called by drivers */
+int in_register_driver(const in_drv_t *drv)
+{
+ int count_new = in_driver_count + 1;
+ in_drv_t *new_drivers;
- for (i = 0; i < IN_DRVID_COUNT; i++) {
- in_drivers[i].prefix = "none:";
- in_drivers[i].probe = in_def_probe;
- in_drivers[i].free = in_def_free;
- 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;
- in_drivers[i].set_config = in_def_set_config;
- in_drivers[i].update_keycode = in_def_update_keycode;
- in_drivers[i].menu_translate = in_def_menu_translate;
- in_drivers[i].get_key_code = in_def_get_key_code;
- in_drivers[i].get_key_name = in_def_get_key_name;
+ new_drivers = realloc(in_drivers, count_new * sizeof(in_drivers[0]));
+ if (new_drivers == NULL) {
+ lprintf("input: in_register_driver OOM\n");
+ return -1;
}
-#ifdef IN_GP2X
- in_gp2x_init(&in_drivers[IN_DRVID_GP2X]);
-#endif
-#ifdef IN_EVDEV
- in_evdev_init(&in_drivers[IN_DRVID_EVDEV]);
-#endif
-#ifdef IN_VK
- in_vk_init(&in_drivers[IN_DRVID_VK]);
-#endif
+ 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_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);
+ in_drivers = new_drivers;
+ in_driver_count = count_new;
+
+ return 0;
+}
+
+void in_init(void)
+{
+ in_drivers = NULL;
+ memset(in_devices, 0, sizeof(in_devices));
+ in_driver_count = 0;
+ in_dev_count = 0;
}
#if 0
#define PEV_MASK 0x7ff80000
-enum {
- IN_DRVID_UNKNOWN = 0,
- IN_DRVID_GP2X,
- IN_DRVID_EVDEV,
- IN_DRVID_VK,
- IN_DRVID_COUNT,
-};
-
enum {
IN_CFG_BIND_COUNT = 0,
IN_CFG_DOES_COMBOS,
const char *prefix;
void (*probe)(void);
void (*free)(void *drv_data);
- int (*get_bind_count)(void);
const char * const *
(*get_key_names)(int *count);
void (*get_def_binds)(int *binds);
int (*clean_binds)(void *drv_data, int *binds, int *def_finds);
int (*get_config)(void *drv_data, int what, int *val);
int (*set_config)(void *drv_data, int what, int val);
+ int (*update)(void *drv_data, const int *binds, int *result);
/* return -1 on no event, -2 on error */
int (*update_keycode)(void *drv_data, int *is_down);
int (*menu_translate)(void *drv_data, int keycode);
};
/* to be called by drivers */
-void in_register(const char *nname, int drv_id, int drv_fd_hnd, void *drv_data,
+int in_register_driver(const in_drv_t *drv);
+void in_register(const char *nname, int drv_fd_hnd, void *drv_data,
int key_count, const char * const *key_names, int combos);
void in_combos_find(const int *binds, int last_key, int *combo_keys, int *combo_acts);
int in_combos_do(int keys, const int *binds, int last_key, int combo_keys, int combo_acts);
int in_evdev_allow_abs_only;
-static const char * const in_evdev_prefix = "evdev:";
+#define IN_EVDEV_PREFIX "evdev:"
+
static const char * const in_evdev_keys[KEY_CNT] = {
[0 ... KEY_MAX] = NULL,
[KEY_RESERVED] = "Reserved", [KEY_ESC] = "Esc",
dev->fd = fd;
dev->kc_first = kc_first;
dev->kc_last = kc_last;
- strcpy(name, in_evdev_prefix);
+ strcpy(name, IN_EVDEV_PREFIX);
ioctl(fd, EVIOCGNAME(sizeof(name)-6), name+6);
printf("in_evdev: found \"%s\" with %d events (type %08x)\n",
name+6, count, support);
- in_register(name, IN_DRVID_EVDEV, fd, dev, KEY_CNT, in_evdev_keys, 0);
+ in_register(name, fd, dev, KEY_CNT, in_evdev_keys, 0);
continue;
skip:
/* ORs result with binds of pressed buttons
* XXX: should measure performance hit of this func, might need to optimize */
-int in_evdev_update(void *drv_data, const int *binds, int *result)
+static int in_evdev_update(void *drv_data, const int *binds, int *result)
{
struct input_event ev[16];
struct input_absinfo ainfo;
return count;
}
-void in_evdev_init(void *vdrv)
+static const in_drv_t in_evdev_drv = {
+ .prefix = IN_EVDEV_PREFIX,
+ .probe = in_evdev_probe,
+ .free = in_evdev_free,
+ .get_key_names = in_evdev_get_key_names,
+ .get_def_binds = in_evdev_get_def_binds,
+ .clean_binds = in_evdev_clean_binds,
+ .set_config = in_evdev_set_config,
+ .update = in_evdev_update,
+ .update_keycode = in_evdev_update_keycode,
+ .menu_translate = in_evdev_menu_translate,
+};
+
+void in_evdev_init(void)
{
- in_drv_t *drv = vdrv;
-
- drv->prefix = in_evdev_prefix;
- drv->probe = in_evdev_probe;
- drv->free = in_evdev_free;
- drv->get_key_names = in_evdev_get_key_names;
- drv->get_def_binds = in_evdev_get_def_binds;
- drv->clean_binds = in_evdev_clean_binds;
- drv->set_config = in_evdev_set_config;
- drv->update_keycode = in_evdev_update_keycode;
- drv->menu_translate = in_evdev_menu_translate;
+ in_register_driver(&in_evdev_drv);
}