mirror of
https://github.com/RaySollium99/libpicofe.git
synced 2025-09-05 06:47:45 -04:00
some input framework attempt
git-svn-id: file:///home/notaz/opt/svn/PicoDrive/platform@621 be3aeb3a-fb24-0410-a615-afba39da0efa
This commit is contained in:
parent
8fc9402d7c
commit
2258f158c4
4 changed files with 254 additions and 73 deletions
193
common/input.c
Normal file
193
common/input.c
Normal file
|
@ -0,0 +1,193 @@
|
||||||
|
#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;
|
||||||
|
}
|
||||||
|
|
8
common/input.h
Normal file
8
common/input.h
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
#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);
|
|
@ -8,24 +8,17 @@
|
||||||
#include <linux/input.h>
|
#include <linux/input.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
|
#include "../common/input.h"
|
||||||
#include "event.h"
|
#include "event.h"
|
||||||
|
|
||||||
#define NUM_DEVS 8
|
|
||||||
#define NUM_KEYS_DOWN 16
|
|
||||||
|
|
||||||
#define BIT(x) (keybits[(x)/sizeof(keybits[0])/8] & \
|
#define BIT(x) (keybits[(x)/sizeof(keybits[0])/8] & \
|
||||||
(1 << ((x) & (sizeof(keybits[0])*8-1))))
|
(1 << ((x) & (sizeof(keybits[0])*8-1))))
|
||||||
|
|
||||||
static int event_fds[NUM_DEVS];
|
int in_evdev_probe(void)
|
||||||
static int event_fd_count = 0;
|
|
||||||
|
|
||||||
int in_event_init(void)
|
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
in_event_exit();
|
for (i = 0;; i++)
|
||||||
|
|
||||||
for (i = 0; event_fd_count < NUM_DEVS; i++)
|
|
||||||
{
|
{
|
||||||
int u, ret, fd, keybits[KEY_MAX/sizeof(int)];
|
int u, ret, fd, keybits[KEY_MAX/sizeof(int)];
|
||||||
int support = 0, count = 0;
|
int support = 0, count = 0;
|
||||||
|
@ -39,7 +32,7 @@ int in_event_init(void)
|
||||||
/* check supported events */
|
/* check supported events */
|
||||||
ret = ioctl(fd, EVIOCGBIT(0, sizeof(support)), &support);
|
ret = ioctl(fd, EVIOCGBIT(0, sizeof(support)), &support);
|
||||||
if (ret == -1) {
|
if (ret == -1) {
|
||||||
printf("in_event: ioctl failed on %s\n", name);
|
printf("in_evdev: ioctl failed on %s\n", name);
|
||||||
goto skip;
|
goto skip;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,73 +41,73 @@ int in_event_init(void)
|
||||||
|
|
||||||
ret = ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(keybits)), keybits);
|
ret = ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(keybits)), keybits);
|
||||||
if (ret == -1) {
|
if (ret == -1) {
|
||||||
printf("in_event: ioctl failed on %s\n", name);
|
printf("in_evdev: ioctl failed on %s\n", name);
|
||||||
goto skip;
|
goto skip;
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("%s: %08x\n", name, support);
|
|
||||||
|
|
||||||
/* check for interesting keys */
|
/* check for interesting keys */
|
||||||
for (u = 0; u < KEY_MAX; u++) {
|
for (u = 0; u < KEY_MAX; u++) {
|
||||||
if (BIT(u) && u != KEY_POWER)
|
if (BIT(u) && u != KEY_POWER && u != KEY_SLEEP)
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (count == 0)
|
if (count == 0)
|
||||||
goto skip;
|
goto skip;
|
||||||
|
|
||||||
ioctl(fd, EVIOCGNAME(sizeof(name)), name);
|
strcpy(name, "evdev:");
|
||||||
printf("event: %d: using \"%s\" with %d events\n",
|
ioctl(fd, EVIOCGNAME(sizeof(name)-6), name+6);
|
||||||
event_fd_count, name, count);
|
printf("in_evdev: found \"%s\" with %d events (type %08x)\n",
|
||||||
event_fds[event_fd_count++] = fd;
|
name+6, count, support);
|
||||||
|
in_register(name, IN_DRVID_EVDEV, (void *)fd);
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
skip:
|
skip:
|
||||||
close(fd);
|
close(fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("event: %d devices found.\n", event_fd_count);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void in_event_exit(void)
|
void in_evdev_free(void *drv_data)
|
||||||
{
|
{
|
||||||
for (; event_fd_count > 0; event_fd_count--)
|
close((int)drv_data);
|
||||||
close(event_fds[event_fd_count - 1]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int in_event_update(int binds[512])
|
int in_evdev_bind_count(void)
|
||||||
|
{
|
||||||
|
return 512;
|
||||||
|
}
|
||||||
|
|
||||||
|
int in_evdev_update(void *drv_data, int *binds)
|
||||||
{
|
{
|
||||||
struct input_event ev[16];
|
struct input_event ev[16];
|
||||||
int d, rd, ret;
|
|
||||||
int result = 0;
|
|
||||||
|
|
||||||
for (d = 0; d < event_fd_count; d++)
|
|
||||||
{
|
|
||||||
int keybits[KEY_MAX/sizeof(int)];
|
int keybits[KEY_MAX/sizeof(int)];
|
||||||
int fd = event_fds[d];
|
int fd = (int)drv_data;
|
||||||
int u, changed = 0;
|
int result = 0, changed = 0;
|
||||||
|
int rd, ret, u;
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
rd = read(fd, ev, sizeof(ev));
|
rd = read(fd, ev, sizeof(ev));
|
||||||
if (rd < (int)sizeof(ev[0])) {
|
if (rd < (int)sizeof(ev[0])) {
|
||||||
if (errno != EAGAIN)
|
if (errno != EAGAIN)
|
||||||
perror("event: read failed");
|
perror("in_evdev: read failed");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
changed = 1;
|
changed = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
if (!changed)
|
if (!changed)
|
||||||
continue;
|
return 0;
|
||||||
|
*/
|
||||||
ret = ioctl(fd, EVIOCGKEY(sizeof(keybits)), keybits);
|
ret = ioctl(fd, EVIOCGKEY(sizeof(keybits)), keybits);
|
||||||
if (ret == -1) {
|
if (ret == -1) {
|
||||||
printf("in_event: ioctl failed on %d\n", d);
|
perror("in_evdev: ioctl failed");
|
||||||
continue;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
printf("#%d: ", fd);
|
||||||
for (u = 0; u < KEY_MAX; u++) {
|
for (u = 0; u < KEY_MAX; u++) {
|
||||||
if (BIT(u)) {
|
if (BIT(u)) {
|
||||||
printf(" %d", u);
|
printf(" %d", u);
|
||||||
|
@ -122,21 +115,7 @@ int in_event_update(int binds[512])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
printf("\n");
|
printf("\n");
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
int main()
|
|
||||||
{
|
|
||||||
in_event_init();
|
|
||||||
|
|
||||||
while (1) {
|
|
||||||
int b[512];
|
|
||||||
in_event_update(b);
|
|
||||||
sleep(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
int in_event_init(void);
|
int in_evdev_probe(void);
|
||||||
void in_event_exit(void);
|
void in_evdev_free(void *drv_data);
|
||||||
int in_event_update(int binds[512]);
|
int in_evdev_bind_count(void);
|
||||||
|
int in_evdev_update(void *drv_data, int *binds);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue