#include "project.h" input_dev_t *input_devs = NULL; static void set_nonblocking (int fd) { long arg = 0; arg = fcntl (fd, F_GETFL, arg); arg |= O_NONBLOCK; fcntl (fd, F_SETFL, arg); } static char * input_dev_name (int i) { static char fn[1024]; sprintf (fn, "/dev/input/event%d", i); return fn; } static input_dev_t * get_input_dev (int id) { input_dev_t *ret; int fd; unsigned short ids[4]; char *fn; for (ret = input_devs; ret; ret = ret->next) if (ret->id == id) return ret; fn = input_dev_name (id); fd = open (fn, O_RDWR); if (fd < 0) return NULL; set_nonblocking (fd); ret = malloc (sizeof (*ret)); bzero (ret, sizeof (*ret)); ret->id = id; ret->fd = fd; ioctl (fd, EVIOCGID, ids); if ((ids[ID_VENDOR] == 0xea0) && (ids[ID_PRODUCT] == 0x2211)) ret->blacklistid = 1; printf ("New input device %s (%d) bus 0x%x vendor 0x%x product 0x%x version 0x%x\n", fn, id, ids[ID_BUS], ids[ID_VENDOR], ids[ID_PRODUCT], ids[ID_VERSION]); ret->next = input_devs; input_devs = ret; return ret; } static void free_input_dev (input_dev_t * d) { printf ("Removid input device %s (%d)\n", input_dev_name (d->id), d->id); if (d->fd > -1) close (d->fd); free (d); } void scan_input_devs (void) { DIR *dir = opendir ("/dev/input"); struct dirent *de; int i; input_dev_t *id, **idp; int version; for (idp = &input_devs; (id = *idp);) { id->present = 0; if (access (input_dev_name (id->id), F_OK) || ioctl (id->fd, EVIOCGVERSION, &version)) { *idp = id->next; free_input_dev (id); } else { idp = &id->next; } } if (dir) { while ((de = readdir (dir))) { if (!strcmp (de->d_name, "event")) continue; i = atoi (de->d_name + 5); id = get_input_dev (i); if (id) id->present = 1; } closedir (dir); } for (idp = &input_devs; (id = *idp);) { if (!id->present) { *idp = id->next; free_input_dev (id); } else { idp = &id->next; } } }