--- /dev/null
+#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;
+}
+
--- /dev/null
+#define IN_DRVID_EVDEV 1
+
+/* to be called by drivers */
+void in_register(const char *nname, int drv_id, void *drv_data);
+
+void in_init(void);
+void in_probe(void);
+int in_update(void);
#include <linux/input.h>
#include <errno.h>
+#include "../common/input.h"
#include "event.h"
-#define NUM_DEVS 8
-#define NUM_KEYS_DOWN 16
-
#define BIT(x) (keybits[(x)/sizeof(keybits[0])/8] & \
(1 << ((x) & (sizeof(keybits[0])*8-1))))
-static int event_fds[NUM_DEVS];
-static int event_fd_count = 0;
-
-int in_event_init(void)
+int in_evdev_probe(void)
{
int i;
- in_event_exit();
-
- for (i = 0; event_fd_count < NUM_DEVS; i++)
+ for (i = 0;; i++)
{
int u, ret, fd, keybits[KEY_MAX/sizeof(int)];
int support = 0, count = 0;
/* check supported events */
ret = ioctl(fd, EVIOCGBIT(0, sizeof(support)), &support);
if (ret == -1) {
- printf("in_event: ioctl failed on %s\n", name);
+ printf("in_evdev: ioctl failed on %s\n", name);
goto skip;
}
ret = ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(keybits)), keybits);
if (ret == -1) {
- printf("in_event: ioctl failed on %s\n", name);
+ printf("in_evdev: ioctl failed on %s\n", name);
goto skip;
}
- printf("%s: %08x\n", name, support);
-
/* check for interesting keys */
for (u = 0; u < KEY_MAX; u++) {
- if (BIT(u) && u != KEY_POWER)
+ if (BIT(u) && u != KEY_POWER && u != KEY_SLEEP)
count++;
}
if (count == 0)
goto skip;
- ioctl(fd, EVIOCGNAME(sizeof(name)), name);
- printf("event: %d: using \"%s\" with %d events\n",
- event_fd_count, name, count);
- event_fds[event_fd_count++] = fd;
+ strcpy(name, "evdev:");
+ 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, (void *)fd);
continue;
skip:
close(fd);
}
- printf("event: %d devices found.\n", event_fd_count);
return 0;
}
-void in_event_exit(void)
+void in_evdev_free(void *drv_data)
+{
+ close((int)drv_data);
+}
+
+int in_evdev_bind_count(void)
{
- for (; event_fd_count > 0; event_fd_count--)
- close(event_fds[event_fd_count - 1]);
+ return 512;
}
-int in_event_update(int binds[512])
+int in_evdev_update(void *drv_data, int *binds)
{
struct input_event ev[16];
- int d, rd, ret;
- int result = 0;
+ int keybits[KEY_MAX/sizeof(int)];
+ int fd = (int)drv_data;
+ int result = 0, changed = 0;
+ int rd, ret, u;
- for (d = 0; d < event_fd_count; d++)
- {
- int keybits[KEY_MAX/sizeof(int)];
- int fd = event_fds[d];
- int u, changed = 0;
-
- while (1) {
- rd = read(fd, ev, sizeof(ev));
- if (rd < (int)sizeof(ev[0])) {
- if (errno != EAGAIN)
- perror("event: read failed");
- break;
- }
-
- changed = 1;
+ while (1) {
+ rd = read(fd, ev, sizeof(ev));
+ if (rd < (int)sizeof(ev[0])) {
+ if (errno != EAGAIN)
+ perror("in_evdev: read failed");
+ break;
}
- if (!changed)
- continue;
+ changed = 1;
+ }
- ret = ioctl(fd, EVIOCGKEY(sizeof(keybits)), keybits);
- if (ret == -1) {
- printf("in_event: ioctl failed on %d\n", d);
- continue;
- }
+/*
+ if (!changed)
+ return 0;
+*/
+ ret = ioctl(fd, EVIOCGKEY(sizeof(keybits)), keybits);
+ if (ret == -1) {
+ perror("in_evdev: ioctl failed");
+ return 0;
+ }
- for (u = 0; u < KEY_MAX; u++) {
- if (BIT(u)) {
- printf(" %d", u);
- result |= binds[u];
- }
+ printf("#%d: ", fd);
+ for (u = 0; u < KEY_MAX; u++) {
+ if (BIT(u)) {
+ printf(" %d", u);
+ result |= binds[u];
}
- printf("\n");
}
+ printf("\n");
return result;
}
-int main()
-{
- in_event_init();
-
- while (1) {
- int b[512];
- in_event_update(b);
- sleep(1);
- }
-
- return 0;
-}
-
-int in_event_init(void);
-void in_event_exit(void);
-int in_event_update(int binds[512]);
+int in_evdev_probe(void);
+void in_evdev_free(void *drv_data);
+int in_evdev_bind_count(void);
+int in_evdev_update(void *drv_data, int *binds);