libpicofe/common/input.c
notaz 2258f158c4 some input framework attempt
git-svn-id: file:///home/notaz/opt/svn/PicoDrive/platform@621 be3aeb3a-fb24-0410-a615-afba39da0efa
2008-12-27 22:39:00 +00:00

193 lines
3.3 KiB
C

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "input.h"
#include "../linux/event.h"
typedef struct
{
int drv_id;
void *drv_data;
int *binds;
char *name;
int probed:1;
int ignore:1;
} in_dev_t;
#define IN_MAX_DEVS 10
static in_dev_t in_devices[IN_MAX_DEVS];
static int in_dev_count = 0;
static int in_bind_count(int drv_id)
{
int count = 0;
#ifdef IN_EVDEV
if (drv_id == IN_DRVID_EVDEV)
count = in_evdev_bind_count();
#endif
if (count <= 0)
printf("input: failed to get bind count for drv %d\n", drv_id);
return count;
}
static int *in_alloc_binds(int drv_id)
{
int count, *ret;
count = in_bind_count(drv_id);
if (count <= 0) {
printf("input: failed to get bind count for drv %d\n", drv_id);
return NULL;
}
ret = malloc(count * sizeof(*ret));
return ret;
}
static void in_free(in_dev_t *dev)
{
if (dev->probed) {
#ifdef IN_EVDEV
if (dev->drv_id == IN_DRVID_EVDEV)
in_evdev_free(dev->drv_data);
#endif
}
dev->probed = 0;
dev->drv_data = NULL;
free(dev->name);
dev->name = NULL;
free(dev->binds);
dev->binds = NULL;
}
/* to be called by drivers */
void in_register(const char *nname, int drv_id, void *drv_data)
{
int i, dupe_count = 0, *binds;
char name[256], *name_end, *tmp;
strncpy(name, nname, sizeof(name));
name[sizeof(name)-12] = 0;
name_end = name + strlen(name);
for (i = 0; i < in_dev_count; i++)
{
if (in_devices[i].name == NULL)
continue;
if (strcmp(in_devices[i].name, name) == 0)
{
if (in_devices[i].probed) {
dupe_count++;
sprintf(name_end, " [%d]", dupe_count);
continue;
}
goto update;
}
}
if (i >= IN_MAX_DEVS)
{
/* try to find unused device */
for (i = 0; i < IN_MAX_DEVS; i++)
if (!in_devices[i].probed) break;
if (i >= IN_MAX_DEVS) {
printf("input: too many devices, can't add %s\n", name);
return;
}
in_free(&in_devices[i]);
}
tmp = strdup(name);
if (tmp == NULL)
return;
binds = in_alloc_binds(drv_id);
if (binds == NULL) {
free(tmp);
return;
}
in_devices[i].name = tmp;
in_devices[i].binds = binds;
if (i + 1 > in_dev_count)
in_dev_count = i + 1;
printf("input: new device #%d \"%s\"\n", i, name);
update:
in_devices[i].probed = 1;
in_devices[i].drv_id = drv_id;
in_devices[i].drv_data = drv_data;
}
void in_probe(void)
{
int i;
for (i = 0; i < in_dev_count; i++)
in_devices[i].probed = 0;
#ifdef IN_EVDEV
in_evdev_probe();
#endif
/* get rid of devs without binds and probes */
for (i = 0; i < in_dev_count; i++) {
if (!in_devices[i].probed && in_devices[i].binds == NULL) {
in_dev_count--;
if (i < in_dev_count) {
free(in_devices[i].name);
memmove(&in_devices[i], &in_devices[i+1],
(in_dev_count - i) * sizeof(in_devices[0]));
}
}
}
}
void in_clear_binds(const char *devname)
{
/* int count;
count = in_bind_count(drv_id);
if (count <= 0) {
printf("input: failed to get bind count for drv %d\n", dev->drv_id);
return NULL;
}
*/
}
int in_update(void)
{
int i, result = 0;
for (i = 0; i < in_dev_count; i++) {
if (in_devices[i].probed && in_devices[i].binds != NULL) {
#ifdef IN_EVDEV
result |= in_evdev_update(in_devices[i].drv_data, in_devices[i].binds);
#endif
}
}
return result;
}
void in_init(void)
{
memset(in_devices, 0, sizeof(in_devices));
in_dev_count = 0;
}
int main(void)
{
in_init();
in_probe();
while (1) {
in_update();
sleep(1);
}
return 0;
}