Hotplug new input devices

This commit is contained in:
Iwan Timmer
2015-05-12 14:39:20 +02:00
parent 25ebfde470
commit 487f2d9f6f
3 changed files with 83 additions and 34 deletions
+65 -14
View File
@@ -46,6 +46,7 @@ struct input_device {
struct libevdev *dev; struct libevdev *dev;
struct mapping map; struct mapping map;
int fd; int fd;
int fdindex;
__s32 mouseDeltaX, mouseDeltaY, mouseScroll; __s32 mouseDeltaX, mouseDeltaY, mouseScroll;
short controllerId; short controllerId;
int buttonFlags; int buttonFlags;
@@ -59,13 +60,19 @@ struct input_device {
static struct pollfd* fds = NULL; static struct pollfd* fds = NULL;
static struct input_device* devices = NULL; static struct input_device* devices = NULL;
static int numDevices = 0; static int numDevices = 0, numFds = 0;
static int assignedControllerIds = 0; static int assignedControllerIds = 0;
static short* currentKey; static short* currentKey;
static short* currentAbs; static short* currentAbs;
static bool* currentReverse; static bool* currentReverse;
static bool autoadd;
static char* defaultMapfile;
static struct udev *udev;
static struct udev_monitor *udev_mon;
static int udev_fdindex;
static void input_init_parms(struct input_device *dev, struct input_abs_parms *parms, int code) { static void input_init_parms(struct input_device *dev, struct input_abs_parms *parms, int code) {
parms->flat = libevdev_get_abs_flat(dev->dev, code); parms->flat = libevdev_get_abs_flat(dev->dev, code);
parms->min = libevdev_get_abs_minimum(dev->dev, code); parms->min = libevdev_get_abs_minimum(dev->dev, code);
@@ -76,14 +83,23 @@ static void input_init_parms(struct input_device *dev, struct input_abs_parms *p
} }
void input_create(char* device, char* mapFile) { void input_create(char* device, char* mapFile) {
int fd = open(device, O_RDONLY|O_NONBLOCK);
if (fd <= 0) {
fprintf(stderr, "Failed to open device %s\n", device);
fflush(stderr);
return;
}
int dev = numDevices; int dev = numDevices;
int fdindex = numFds;
numDevices++; numDevices++;
numFds++;
if (fds == NULL) { if (fds == NULL) {
fds = malloc(sizeof(struct pollfd)); fds = malloc(sizeof(struct pollfd));
devices = malloc(sizeof(struct input_device)); devices = malloc(sizeof(struct input_device));
} else { } else {
fds = realloc(fds, sizeof(struct pollfd)*numDevices); fds = realloc(fds, sizeof(struct pollfd)*numFds);
devices = realloc(devices, sizeof(struct input_device)*numDevices); devices = realloc(devices, sizeof(struct input_device)*numDevices);
} }
@@ -92,16 +108,12 @@ void input_create(char* device, char* mapFile) {
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
devices[dev].fd = open(device, O_RDONLY|O_NONBLOCK); devices[dev].fd = fd;
if (devices[dev].fd <= 0) {
fprintf(stderr, "Failed to open device %s\n", device);
return;
}
devices[dev].dev = libevdev_new(); devices[dev].dev = libevdev_new();
libevdev_set_fd(devices[dev].dev, devices[dev].fd); libevdev_set_fd(devices[dev].dev, devices[dev].fd);
fds[dev].fd = devices[dev].fd; devices[dev].fdindex = fdindex;
fds[dev].events = POLLIN; fds[fdindex].fd = devices[dev].fd;
fds[fdindex].events = POLLIN;
if (mapFile != NULL) if (mapFile != NULL)
mapping_load(mapFile, &(devices[dev].map)); mapping_load(mapFile, &(devices[dev].map));
@@ -117,13 +129,14 @@ void input_create(char* device, char* mapFile) {
input_init_parms(&devices[dev], &(devices[dev].dpadyParms), devices[dev].map.abs_dpad_y); input_init_parms(&devices[dev], &(devices[dev].dpadyParms), devices[dev].map.abs_dpad_y);
} }
void input_autoload(char* mapfile) { void input_init(char* mapfile) {
struct udev *udev = udev_new(); udev = udev_new();
if (!udev) { if (!udev) {
fprintf(stderr, "Can't create udev\n"); fprintf(stderr, "Can't create udev\n");
exit(1); exit(1);
} }
if (autoadd = numDevices == 0) {
struct udev_enumerate *enumerate = udev_enumerate_new(udev); struct udev_enumerate *enumerate = udev_enumerate_new(udev);
udev_enumerate_add_match_subsystem(enumerate, "input"); udev_enumerate_add_match_subsystem(enumerate, "input");
udev_enumerate_scan_devices(enumerate); udev_enumerate_scan_devices(enumerate);
@@ -142,7 +155,31 @@ void input_autoload(char* mapfile) {
} }
udev_enumerate_unref(enumerate); udev_enumerate_unref(enumerate);
}
udev_mon = udev_monitor_new_from_netlink(udev, "udev");
udev_monitor_filter_add_match_subsystem_devtype(udev_mon, "input", NULL);
udev_monitor_enable_receiving(udev_mon);
int udev_fdindex = numFds;
numFds++;
if (fds == NULL)
fds = malloc(sizeof(struct pollfd));
else
fds = realloc(fds, sizeof(struct pollfd)*numFds);
if (fds == NULL) {
fprintf(stderr, "Not enough memory\n");
exit(EXIT_FAILURE);
}
defaultMapfile = mapfile;
fds[udev_fdindex].fd = udev_monitor_get_fd(udev_mon);
fds[udev_fdindex].events = POLLIN;
}
void input_destroy() {
udev_unref(udev); udev_unref(udev);
} }
@@ -370,9 +407,23 @@ static bool input_handle_mapping_event(struct input_event *ev, struct input_devi
} }
static void input_poll(bool (*handler) (struct input_event*, struct input_device*)) { static void input_poll(bool (*handler) (struct input_event*, struct input_device*)) {
while (poll(fds, numDevices, -1)) { while (poll(fds, numFds, -1)) {
if (fds[udev_fdindex].revents > 0) {
struct udev_device *dev = udev_monitor_receive_device(udev_mon);
const char *action = udev_device_get_action(dev);
if (action != NULL) {
if (autoadd && strcmp("add", action) == 0) {
const char *devnode = udev_device_get_devnode(dev);
int id;
if (devnode != NULL && sscanf(devnode, "/dev/input/event%d", &id) == 1) {
input_create(devnode, defaultMapfile);
}
}
udev_device_unref(dev);
}
}
for (int i=0;i<numDevices;i++) { for (int i=0;i<numDevices;i++) {
if (fds[i].revents > 0) { if (fds[devices[i].fdindex].revents > 0) {
int rc; int rc;
struct input_event ev; struct input_event ev;
while ((rc = libevdev_next_event(devices[i].dev, LIBEVDEV_READ_FLAG_NORMAL, &ev)) >= 0) { while ((rc = libevdev_next_event(devices[i].dev, LIBEVDEV_READ_FLAG_NORMAL, &ev)) >= 0) {
+3 -1
View File
@@ -17,7 +17,9 @@
* along with Moonlight; if not, see <http://www.gnu.org/licenses/>. * along with Moonlight; if not, see <http://www.gnu.org/licenses/>.
*/ */
void input_autoload(char* mapfile); void input_init(char* mapfile);
void input_create(char* device, char* mapFile); void input_create(char* device, char* mapFile);
void input_loop(); void input_loop();
void input_map(char* fileName); void input_map(char* fileName);
void input_destroy();
+1 -5
View File
@@ -122,7 +122,6 @@ int main(int argc, char* argv[]) {
char* action = NULL; char* action = NULL;
char* address = NULL; char* address = NULL;
char* mapping = NULL; char* mapping = NULL;
bool inputs = false;
int option_index = 0; int option_index = 0;
bool sops = true; bool sops = true;
bool localaudio = false; bool localaudio = false;
@@ -160,7 +159,6 @@ int main(int argc, char* argv[]) {
break; break;
case 'j': case 'j':
input_create(optarg, mapping); input_create(optarg, mapping);
inputs = true;
break; break;
case 'k': case 'k':
mapping = optarg; mapping = optarg;
@@ -211,9 +209,7 @@ int main(int argc, char* argv[]) {
} }
} }
if (!inputs) { input_init(mapping);
input_autoload(mapping);
}
client_init(address); client_init(address);