mirror of
https://github.com/moonlight-stream/moonlight-embedded.git
synced 2026-06-17 22:32:43 +00:00
Hotplug new input devices
This commit is contained in:
+65
-14
@@ -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
@@ -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
@@ -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);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user