Single mapping file for all inputs

This commit is contained in:
Iwan Timmer 2017-04-08 15:50:24 +02:00
parent 9f43712fc8
commit 1d7c2be7e2
13 changed files with 131 additions and 89 deletions

View File

@ -128,8 +128,8 @@ By default the encryption keys are stored in $XDG_CACHE_DIR/moonlight or ~/.cach
=item B<-mapping> [I<MAPPING>] =item B<-mapping> [I<MAPPING>]
Use I<MAPPING> as the mapping file for all inputs specified after this B<-mapping>. Use I<MAPPING> as the mapping file for all inputs.
If no B<-input> is specified after the B<-mapping> this mapping is used for autoloaded inputs. This mapping file should have the same format as the gamecontrollerdb.txt for SDL.
=item B<-input> [I<INPUT>] =item B<-input> [I<INPUT>]

View File

@ -1,7 +1,7 @@
/* /*
* This file is part of Moonlight Embedded. * This file is part of Moonlight Embedded.
* *
* Copyright (C) 2015, 2016 Iwan Timmer * Copyright (C) 2015-2017 Iwan Timmer
* *
* Moonlight is free software; you can redistribute it and/or modify * Moonlight is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -37,7 +37,6 @@
#define write_config_bool(fd, key, value) fprintf(fd, "%s = %s\n", key, value?"true":"false"); #define write_config_bool(fd, key, value) fprintf(fd, "%s = %s\n", key, value?"true":"false");
bool inputAdded = false; bool inputAdded = false;
static bool mapped = true;
const char* audio_device = NULL; const char* audio_device = NULL;
static struct option long_options[] = { static struct option long_options[] = {
@ -152,11 +151,9 @@ static void parse_argument(int c, char* value, PCONFIGURATION config) {
perror("Too many inputs specified"); perror("Too many inputs specified");
exit(-1); exit(-1);
} }
config->inputs[config->inputsCount].path = value; config->inputs[config->inputsCount] = value;
config->inputs[config->inputsCount].mapping = config->mapping;
config->inputsCount++; config->inputsCount++;
inputAdded = true; inputAdded = true;
mapped = true;
break; break;
case 'k': case 'k':
config->mapping = get_path(value, getenv("XDG_DATA_DIRS")); config->mapping = get_path(value, getenv("XDG_DATA_DIRS"));
@ -164,7 +161,6 @@ static void parse_argument(int c, char* value, PCONFIGURATION config) {
fprintf(stderr, "Unable to open custom mapping file: %s\n", value); fprintf(stderr, "Unable to open custom mapping file: %s\n", value);
exit(-1); exit(-1);
} }
mapped = false;
break; break;
case 'l': case 'l':
config->sops = false; config->sops = false;
@ -352,10 +348,7 @@ void config_parse(int argc, char* argv[], PCONFIGURATION config) {
} }
if (inputAdded) { if (inputAdded) {
if (!mapped) { if (config->mapping == NULL) {
fprintf(stderr, "Mapping option should be followed by the input to be mapped.\n");
exit(-1);
} else if (config->mapping == NULL) {
fprintf(stderr, "Please specify mapping file as default mapping could not be found.\n"); fprintf(stderr, "Please specify mapping file as default mapping could not be found.\n");
exit(-1); exit(-1);
} }

View File

@ -1,7 +1,7 @@
/* /*
* This file is part of Moonlight Embedded. * This file is part of Moonlight Embedded.
* *
* Copyright (C) 2015, 2016 Iwan Timmer * Copyright (C) 2015-2017 Iwan Timmer
* *
* Moonlight is free software; you can redistribute it and/or modify * Moonlight is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -25,11 +25,6 @@
enum codecs { CODEC_UNSPECIFIED, CODEC_H264, CODEC_HEVC }; enum codecs { CODEC_UNSPECIFIED, CODEC_H264, CODEC_HEVC };
struct input_config {
char* path;
char* mapping;
};
typedef struct _CONFIGURATION { typedef struct _CONFIGURATION {
STREAM_CONFIGURATION stream; STREAM_CONFIGURATION stream;
char* app; char* app;
@ -44,7 +39,7 @@ typedef struct _CONFIGURATION {
bool fullscreen; bool fullscreen;
bool forcehw; bool forcehw;
bool unsupported_version; bool unsupported_version;
struct input_config inputs[MAX_INPUTS]; char* inputs[MAX_INPUTS];
int inputsCount; int inputsCount;
enum codecs codec; enum codecs codec;
} CONFIGURATION, *PCONFIGURATION; } CONFIGURATION, *PCONFIGURATION;

View File

@ -38,6 +38,13 @@
#include <limits.h> #include <limits.h>
#include <unistd.h> #include <unistd.h>
#include <pthread.h> #include <pthread.h>
#include <endian.h>
#if __BYTE_ORDER == __LITTLE_ENDIAN
#define int16_to_le(val) val
#else
#define int16_to_le(val) ((((val) >> 8) & 0x00FF) | (((val) << 8) & 0xFF00))
#endif
struct input_abs_parms { struct input_abs_parms {
int min, max; int min, max;
@ -48,7 +55,7 @@ struct input_abs_parms {
struct input_device { struct input_device {
struct libevdev *dev; struct libevdev *dev;
struct mapping map; struct mapping* map;
int key_map[KEY_MAX]; int key_map[KEY_MAX];
int abs_map[ABS_MAX]; int abs_map[ABS_MAX];
int hats_state[3][2]; int hats_state[3][2];
@ -209,35 +216,35 @@ static bool evdev_handle_event(struct input_event *ev, struct input_device *dev)
mouseCode = BUTTON_RIGHT; mouseCode = BUTTON_RIGHT;
break; break;
default: default:
if (index == dev->map.btn_a) if (index == dev->map->btn_a)
gamepadCode = A_FLAG; gamepadCode = A_FLAG;
else if (index == dev->map.btn_x) else if (index == dev->map->btn_x)
gamepadCode = X_FLAG; gamepadCode = X_FLAG;
else if (index == dev->map.btn_y) else if (index == dev->map->btn_y)
gamepadCode = Y_FLAG; gamepadCode = Y_FLAG;
else if (index == dev->map.btn_b) else if (index == dev->map->btn_b)
gamepadCode = B_FLAG; gamepadCode = B_FLAG;
else if (index == dev->map.btn_dpup) else if (index == dev->map->btn_dpup)
gamepadCode = UP_FLAG; gamepadCode = UP_FLAG;
else if (index == dev->map.btn_dpdown) else if (index == dev->map->btn_dpdown)
gamepadCode = DOWN_FLAG; gamepadCode = DOWN_FLAG;
else if (index == dev->map.btn_dpright) else if (index == dev->map->btn_dpright)
gamepadCode = RIGHT_FLAG; gamepadCode = RIGHT_FLAG;
else if (index == dev->map.btn_dpleft) else if (index == dev->map->btn_dpleft)
gamepadCode = LEFT_FLAG; gamepadCode = LEFT_FLAG;
else if (index == dev->map.btn_leftstick) else if (index == dev->map->btn_leftstick)
gamepadCode = LS_CLK_FLAG; gamepadCode = LS_CLK_FLAG;
else if (index == dev->map.btn_rightstick) else if (index == dev->map->btn_rightstick)
gamepadCode = RS_CLK_FLAG; gamepadCode = RS_CLK_FLAG;
else if (index == dev->map.btn_leftshoulder) else if (index == dev->map->btn_leftshoulder)
gamepadCode = LB_FLAG; gamepadCode = LB_FLAG;
else if (index == dev->map.btn_rightshoulder) else if (index == dev->map->btn_rightshoulder)
gamepadCode = RB_FLAG; gamepadCode = RB_FLAG;
else if (index == dev->map.btn_start) else if (index == dev->map->btn_start)
gamepadCode = PLAY_FLAG; gamepadCode = PLAY_FLAG;
else if (index == dev->map.btn_back) else if (index == dev->map->btn_back)
gamepadCode = BACK_FLAG; gamepadCode = BACK_FLAG;
else if (index == dev->map.btn_guide) else if (index == dev->map->btn_guide)
gamepadCode = SPECIAL_FLAG; gamepadCode = SPECIAL_FLAG;
} }
@ -251,9 +258,9 @@ static bool evdev_handle_event(struct input_event *ev, struct input_device *dev)
dev->buttonFlags |= gamepadCode; dev->buttonFlags |= gamepadCode;
else else
dev->buttonFlags &= ~gamepadCode; dev->buttonFlags &= ~gamepadCode;
} else if (index == dev->map.btn_lefttrigger) } else if (index == dev->map->btn_lefttrigger)
dev->leftTrigger = ev->value?UCHAR_MAX:0; dev->leftTrigger = ev->value?UCHAR_MAX:0;
else if (index == dev->map.btn_righttrigger) else if (index == dev->map->btn_righttrigger)
dev->rightTrigger = ev->value?UCHAR_MAX:0; dev->rightTrigger = ev->value?UCHAR_MAX:0;
else { else {
fprintf(stderr, "Unmapped button: %d\n", ev->code); fprintf(stderr, "Unmapped button: %d\n", ev->code);
@ -292,28 +299,28 @@ static bool evdev_handle_event(struct input_event *ev, struct input_device *dev)
case ABS_HAT3Y: case ABS_HAT3Y:
dev->hats_state[hat_index][har_dir_index] = ev->value < 0 ? 0 : (ev->value == 0 ? 1 : 2); dev->hats_state[hat_index][har_dir_index] = ev->value < 0 ? 0 : (ev->value == 0 ? 1 : 2);
int hat_state = hat_constants[dev->hats_state[hat_index][0]][dev->hats_state[hat_index][1]]; int hat_state = hat_constants[dev->hats_state[hat_index][0]][dev->hats_state[hat_index][1]];
if (hat_index == dev->map.hat_dpup) if (hat_index == dev->map->hat_dpup)
set_hat(dev->buttonFlags, UP_FLAG, hat_state, dev->map.hat_dir_dpup); set_hat(dev->buttonFlags, UP_FLAG, hat_state, dev->map->hat_dir_dpup);
if (hat_index == dev->map.hat_dpdown) if (hat_index == dev->map->hat_dpdown)
set_hat(dev->buttonFlags, DOWN_FLAG, hat_state, dev->map.hat_dir_dpdown); set_hat(dev->buttonFlags, DOWN_FLAG, hat_state, dev->map->hat_dir_dpdown);
if (hat_index == dev->map.hat_dpright) if (hat_index == dev->map->hat_dpright)
set_hat(dev->buttonFlags, HAT_RIGHT, hat_state, dev->map.hat_dir_dpright); set_hat(dev->buttonFlags, HAT_RIGHT, hat_state, dev->map->hat_dir_dpright);
if (hat_index == dev->map.hat_dpleft) if (hat_index == dev->map->hat_dpleft)
set_hat(dev->buttonFlags, HAT_LEFT, hat_state, dev->map.hat_dir_dpleft); set_hat(dev->buttonFlags, HAT_LEFT, hat_state, dev->map->hat_dir_dpleft);
break; break;
} }
default: default:
if (index == dev->map.abs_leftx) if (index == dev->map->abs_leftx)
dev->leftStickX = evdev_convert_value(ev, dev, &dev->xParms, dev->map.reverse_leftx); dev->leftStickX = evdev_convert_value(ev, dev, &dev->xParms, dev->map->reverse_leftx);
else if (index == dev->map.abs_lefty) else if (index == dev->map->abs_lefty)
dev->leftStickY = evdev_convert_value(ev, dev, &dev->yParms, !dev->map.reverse_lefty); dev->leftStickY = evdev_convert_value(ev, dev, &dev->yParms, !dev->map->reverse_lefty);
else if (index == dev->map.abs_rightx) else if (index == dev->map->abs_rightx)
dev->rightStickX = evdev_convert_value(ev, dev, &dev->rxParms, dev->map.reverse_rightx); dev->rightStickX = evdev_convert_value(ev, dev, &dev->rxParms, dev->map->reverse_rightx);
else if (index == dev->map.abs_righty) else if (index == dev->map->abs_righty)
dev->rightStickY = evdev_convert_value(ev, dev, &dev->ryParms, !dev->map.reverse_righty); dev->rightStickY = evdev_convert_value(ev, dev, &dev->ryParms, !dev->map->reverse_righty);
else if (index == dev->map.abs_lefttrigger) else if (index == dev->map->abs_lefttrigger)
dev->leftTrigger = evdev_convert_value_byte(ev, dev, &dev->zParms); dev->leftTrigger = evdev_convert_value_byte(ev, dev, &dev->zParms);
else if (index == dev->map.abs_righttrigger) else if (index == dev->map->abs_righttrigger)
dev->rightTrigger = evdev_convert_value_byte(ev, dev, &dev->rzParms); dev->rightTrigger = evdev_convert_value_byte(ev, dev, &dev->rzParms);
else else
gamepadModified = false; gamepadModified = false;
@ -383,7 +390,7 @@ static int evdev_handle(int fd) {
return LOOP_OK; return LOOP_OK;
} }
void evdev_create(const char* device, char* mapFile) { void evdev_create(const char* device, struct mapping* mappings) {
int fd = open(device, O_RDONLY|O_NONBLOCK); int fd = open(device, O_RDONLY|O_NONBLOCK);
if (fd <= 0) { if (fd <= 0) {
fprintf(stderr, "Failed to open device %s\n", device); fprintf(stderr, "Failed to open device %s\n", device);
@ -391,6 +398,31 @@ void evdev_create(const char* device, char* mapFile) {
return; return;
} }
struct libevdev *evdev = libevdev_new();
libevdev_set_fd(evdev, fd);
int16_t guid[8] = {0};
guid[0] = int16_to_le(libevdev_get_id_bustype(evdev));
guid[2] = int16_to_le(libevdev_get_id_vendor(evdev));
guid[4] = int16_to_le(libevdev_get_id_product(evdev));
guid[6] = int16_to_le(libevdev_get_id_version(evdev));
char str_guid[33];
char* buf = str_guid;
for (int i = 0; i < 16; i++)
buf += sprintf(buf, "%02x", ((unsigned char*) guid)[i]);
while (mappings != NULL && strncmp(str_guid, mappings->guid, 32) != 0)
mappings = mappings->next;
if (mappings == NULL) {
fprintf(stderr, "No mapping available for %s\n", device);
fflush(stderr);
close(fd);
libevdev_free(evdev);
return;
}
int dev = numDevices; int dev = numDevices;
numDevices++; numDevices++;
@ -407,11 +439,8 @@ void evdev_create(const char* device, char* mapFile) {
memset(&devices[dev], 0, sizeof(devices[0])); memset(&devices[dev], 0, sizeof(devices[0]));
devices[dev].fd = fd; devices[dev].fd = fd;
devices[dev].dev = libevdev_new(); devices[dev].dev = evdev;
libevdev_set_fd(devices[dev].dev, devices[dev].fd); devices[dev].map = mappings;
if (mapFile != NULL)
mapping_load(mapFile, &(devices[dev].map));
int nbuttons = 0; int nbuttons = 0;
for (int i = BTN_JOYSTICK; i < KEY_MAX; ++i) { for (int i = BTN_JOYSTICK; i < KEY_MAX; ++i) {
@ -433,12 +462,12 @@ void evdev_create(const char* device, char* mapFile) {
} }
devices[dev].controllerId = -1; devices[dev].controllerId = -1;
evdev_init_parms(&devices[dev], &(devices[dev].xParms), devices[dev].map.abs_leftx); evdev_init_parms(&devices[dev], &(devices[dev].xParms), devices[dev].map->abs_leftx);
evdev_init_parms(&devices[dev], &(devices[dev].yParms), devices[dev].map.abs_lefty); evdev_init_parms(&devices[dev], &(devices[dev].yParms), devices[dev].map->abs_lefty);
evdev_init_parms(&devices[dev], &(devices[dev].zParms), devices[dev].map.abs_lefttrigger); evdev_init_parms(&devices[dev], &(devices[dev].zParms), devices[dev].map->abs_lefttrigger);
evdev_init_parms(&devices[dev], &(devices[dev].rxParms), devices[dev].map.abs_rightx); evdev_init_parms(&devices[dev], &(devices[dev].rxParms), devices[dev].map->abs_rightx);
evdev_init_parms(&devices[dev], &(devices[dev].ryParms), devices[dev].map.abs_righty); evdev_init_parms(&devices[dev], &(devices[dev].ryParms), devices[dev].map->abs_righty);
evdev_init_parms(&devices[dev], &(devices[dev].rzParms), devices[dev].map.abs_righttrigger); evdev_init_parms(&devices[dev], &(devices[dev].rzParms), devices[dev].map->abs_righttrigger);
if (grabbingDevices) { if (grabbingDevices) {
if (ioctl(fd, EVIOCGRAB, 1) < 0) { if (ioctl(fd, EVIOCGRAB, 1) < 0) {

View File

@ -17,7 +17,7 @@
* along with Moonlight; if not, see <http://www.gnu.org/licenses/>. * along with Moonlight; if not, see <http://www.gnu.org/licenses/>.
*/ */
void evdev_create(const char* device, char* mapFile); void evdev_create(const char* device, struct mapping* mappings);
void evdev_loop(); void evdev_loop();
void evdev_init(); void evdev_init();

View File

@ -23,7 +23,9 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
void mapping_load(char* fileName, struct mapping* map) { struct mapping* mapping_load(char* fileName) {
struct mapping* mappings = NULL;
struct mapping* map = NULL;
FILE* fd = fopen(fileName, "r"); FILE* fd = fopen(fileName, "r");
if (fd == NULL) { if (fd == NULL) {
fprintf(stderr, "Can't open mapping file: %s\n", fileName); fprintf(stderr, "Can't open mapping file: %s\n", fileName);
@ -39,6 +41,17 @@ void mapping_load(char* fileName, struct mapping* map) {
if (guid == NULL || name == NULL) if (guid == NULL || name == NULL)
continue; continue;
struct mapping* newmap = malloc(sizeof(struct mapping));
if (newmap == NULL) {
fprintf(stderr, "Not enough memory");
exit(EXIT_FAILURE);
} else if (mappings == NULL)
mappings = newmap;
else
map->next = newmap;
map = newmap;
strncpy(map->guid, guid, sizeof(map->guid)); strncpy(map->guid, guid, sizeof(map->guid));
strncpy(map->name, name, sizeof(map->name)); strncpy(map->name, name, sizeof(map->name));
@ -133,4 +146,6 @@ void mapping_load(char* fileName, struct mapping* map) {
map->platform[32] = '\0'; map->platform[32] = '\0';
} }
free(line); free(line);
return mappings;
} }

View File

@ -17,6 +17,8 @@
* along with Moonlight; if not, see <http://www.gnu.org/licenses/>. * along with Moonlight; if not, see <http://www.gnu.org/licenses/>.
*/ */
#pragma once
#include <stdbool.h> #include <stdbool.h>
struct mapping { struct mapping {
@ -41,6 +43,8 @@ struct mapping {
short abs_lefttrigger, abs_righttrigger; short abs_lefttrigger, abs_righttrigger;
short btn_lefttrigger, btn_righttrigger; short btn_lefttrigger, btn_righttrigger;
struct mapping* next;
}; };
void mapping_load(char* fileName, struct mapping* map); struct mapping* mapping_load(char* fileName);

View File

@ -1,7 +1,7 @@
/* /*
* This file is part of Moonlight Embedded. * This file is part of Moonlight Embedded.
* *
* Copyright (C) 2015 Iwan Timmer * Copyright (C) 2015-2017 Iwan Timmer
* *
* Moonlight is free software; you can redistribute it and/or modify * Moonlight is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -43,11 +43,11 @@ static GAMEPAD_STATE gamepads[4];
static int keyboard_modifiers; static int keyboard_modifiers;
static int activeGamepadMask = 0; static int activeGamepadMask = 0;
void sdlinput_init() { void sdlinput_init(char* mappings) {
memset(gamepads, 0, sizeof(gamepads)); memset(gamepads, 0, sizeof(gamepads));
SDL_InitSubSystem(SDL_INIT_GAMECONTROLLER); SDL_InitSubSystem(SDL_INIT_GAMECONTROLLER);
SDL_GameControllerAddMappingsFromFile("gamecontrollerdb.txt"); SDL_GameControllerAddMappingsFromFile(mappings);
for (int i = 0; i < SDL_NumJoysticks(); ++i) { for (int i = 0; i < SDL_NumJoysticks(); ++i) {
if (SDL_IsGameController(i)) { if (SDL_IsGameController(i)) {

View File

@ -1,7 +1,7 @@
/* /*
* This file is part of Moonlight Embedded. * This file is part of Moonlight Embedded.
* *
* Copyright (C) 2015 Iwan Timmer * Copyright (C) 2015-2017 Iwan Timmer
* *
* Moonlight is free software; you can redistribute it and/or modify * Moonlight is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -51,7 +51,7 @@ static const short keyCodes[] = {
0x26, //SDLK_UP 0x26, //SDLK_UP
}; };
void sdlinput_init(); void sdlinput_init(char* mappings);
int sdlinput_handle_event(SDL_Event* event); int sdlinput_handle_event(SDL_Event* event);
#endif /* HAVE_SDL */ #endif /* HAVE_SDL */

View File

@ -1,7 +1,7 @@
/* /*
* This file is part of Moonlight Embedded. * This file is part of Moonlight Embedded.
* *
* Copyright (C) 2015 Iwan Timmer * Copyright (C) 2015-2017 Iwan Timmer
* *
* Moonlight is free software; you can redistribute it and/or modify * Moonlight is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -19,6 +19,7 @@
#include "../loop.h" #include "../loop.h"
#include "udev.h"
#include "evdev.h" #include "evdev.h"
#include <libudev.h> #include <libudev.h>
@ -31,7 +32,7 @@
#include <poll.h> #include <poll.h>
static bool autoadd; static bool autoadd;
static char* defaultMapfile; static struct mapping* defaultMappings;
static struct udev *udev; static struct udev *udev;
static struct udev_monitor *udev_mon; static struct udev_monitor *udev_mon;
@ -45,7 +46,7 @@ static int udev_handle(int fd) {
const char *devnode = udev_device_get_devnode(dev); const char *devnode = udev_device_get_devnode(dev);
int id; int id;
if (devnode != NULL && sscanf(devnode, "/dev/input/event%d", &id) == 1) { if (devnode != NULL && sscanf(devnode, "/dev/input/event%d", &id) == 1) {
evdev_create(devnode, defaultMapfile); evdev_create(devnode, defaultMappings);
} }
} }
udev_device_unref(dev); udev_device_unref(dev);
@ -53,7 +54,7 @@ static int udev_handle(int fd) {
return LOOP_OK; return LOOP_OK;
} }
void udev_init(bool autoload, char* mapfile) { void udev_init(bool autoload, struct mapping* mappings) {
udev = udev_new(); udev = udev_new();
if (!udev) { if (!udev) {
fprintf(stderr, "Can't create udev\n"); fprintf(stderr, "Can't create udev\n");
@ -74,7 +75,7 @@ void udev_init(bool autoload, char* mapfile) {
const char *devnode = udev_device_get_devnode(dev); const char *devnode = udev_device_get_devnode(dev);
int id; int id;
if (devnode != NULL && sscanf(devnode, "/dev/input/event%d", &id) == 1) { if (devnode != NULL && sscanf(devnode, "/dev/input/event%d", &id) == 1) {
evdev_create(devnode, mapfile); evdev_create(devnode, mappings);
} }
udev_device_unref(dev); udev_device_unref(dev);
} }
@ -86,7 +87,7 @@ void udev_init(bool autoload, char* mapfile) {
udev_monitor_filter_add_match_subsystem_devtype(udev_mon, "input", NULL); udev_monitor_filter_add_match_subsystem_devtype(udev_mon, "input", NULL);
udev_monitor_enable_receiving(udev_mon); udev_monitor_enable_receiving(udev_mon);
defaultMapfile = mapfile; defaultMappings = mappings;
int udev_fd = udev_monitor_get_fd(udev_mon); int udev_fd = udev_monitor_get_fd(udev_mon);
loop_add_fd(udev_fd, &udev_handle, POLLIN); loop_add_fd(udev_fd, &udev_handle, POLLIN);

View File

@ -17,5 +17,7 @@
* along with Moonlight; if not, see <http://www.gnu.org/licenses/>. * along with Moonlight; if not, see <http://www.gnu.org/licenses/>.
*/ */
void udev_init(bool autoload, char* mapfile); #include "mapping.h"
void udev_init(bool autoload, struct mapping* mappings);
void evdev_destroy(); void evdev_destroy();

View File

@ -28,6 +28,7 @@
#include "platform.h" #include "platform.h"
#include "sdl.h" #include "sdl.h"
#include "input/mapping.h"
#include "input/evdev.h" #include "input/evdev.h"
#include "input/udev.h" #include "input/udev.h"
#include "input/cec.h" #include "input/cec.h"
@ -145,13 +146,13 @@ static void help() {
printf("\t-localaudio\t\tPlay audio locally\n"); printf("\t-localaudio\t\tPlay audio locally\n");
printf("\t-surround\t\tStream 5.1 surround sound (requires GFE 2.7)\n"); printf("\t-surround\t\tStream 5.1 surround sound (requires GFE 2.7)\n");
printf("\t-keydir <directory>\tLoad encryption keys from directory\n"); printf("\t-keydir <directory>\tLoad encryption keys from directory\n");
printf("\t-mapping <file>\t\tUse <file> as gamepad mappings configuration file\n");
#ifdef HAVE_SDL #ifdef HAVE_SDL
printf("\n Video options (SDL Only)\n\n"); printf("\n Video options (SDL Only)\n\n");
printf("\t-windowed\t\tDisplay screen in a window\n"); printf("\t-windowed\t\tDisplay screen in a window\n");
#endif #endif
#ifdef HAVE_EMBEDDED #ifdef HAVE_EMBEDDED
printf("\n I/O options\n\n"); printf("\n I/O options\n\n");
printf("\t-mapping <file>\t\tUse <file> as gamepad mapping configuration file (use before -input)\n");
printf("\t-input <device>\t\tUse <device> as input. Can be used multiple times\n"); printf("\t-input <device>\t\tUse <device> as input. Can be used multiple times\n");
printf("\t-audio <device>\t\tUse <device> as audio output device\n"); printf("\t-audio <device>\t\tUse <device> as audio output device\n");
printf("\t-forcehw \t\tTry to use video hardware acceleration\n"); printf("\t-forcehw \t\tTry to use video hardware acceleration\n");
@ -231,20 +232,24 @@ int main(int argc, char* argv[]) {
} else if (strcmp("stream", config.action) == 0) { } else if (strcmp("stream", config.action) == 0) {
pair_check(&server); pair_check(&server);
if (IS_EMBEDDED(system)) { if (IS_EMBEDDED(system)) {
struct mapping* mappings = mapping_load(config.mapping);
for (int i=0;i<config.inputsCount;i++) { for (int i=0;i<config.inputsCount;i++) {
printf("Add input %s (mapping %s)...\n", config.inputs[i].path, config.inputs[i].mapping); printf("Add input %s...\n", config.inputs[i]);
evdev_create(config.inputs[i].path, config.inputs[i].mapping); evdev_create(config.inputs[i], mappings);
} }
udev_init(!inputAdded, config.mapping); udev_init(!inputAdded, mappings);
evdev_init(); evdev_init();
#ifdef HAVE_LIBCEC #ifdef HAVE_LIBCEC
cec_init(); cec_init();
#endif /* HAVE_LIBCEC */ #endif /* HAVE_LIBCEC */
} }
#ifdef HAVE_SDL #ifdef HAVE_SDL
else if (system == SDL) else if (system == SDL) {
sdl_init(config.stream.width, config.stream.height, config.fullscreen); sdl_init(config.stream.width, config.stream.height, config.fullscreen);
sdlinput_init(config.mapping);
}
#endif #endif
stream(&server, &config, system); stream(&server, &config, system);

View File

@ -68,8 +68,6 @@ void sdl_init(int width, int height, bool fullscreen) {
fprintf(stderr, "Couldn't create mutex\n"); fprintf(stderr, "Couldn't create mutex\n");
exit(1); exit(1);
} }
sdlinput_init();
} }
void sdl_loop() { void sdl_loop() {