Start adding udev input driver.

This commit is contained in:
Themaister 2013-12-07 14:13:40 +01:00
parent 6615f57971
commit c21310b261
10 changed files with 499 additions and 197 deletions

View File

@ -328,7 +328,7 @@ ifeq ($(HAVE_UDEV), 1)
DEFINES += $(UDEV_CFLAGS)
LIBS += $(UDEV_LIBS)
JOYCONFIG_LIBS += $(UDEV_LIBS)
OBJ += input/udev_joypad.o
OBJ += input/udev_input.o input/udev_joypad.o
JOYCONFIG_OBJ += tools/udev_joypad.o
endif

View File

@ -75,6 +75,7 @@ enum
INPUT_XENON360,
INPUT_WII,
INPUT_XINPUT,
INPUT_UDEV,
INPUT_LINUXRAW,
INPUT_APPLE,
INPUT_QNX,
@ -175,6 +176,8 @@ enum
#define INPUT_DEFAULT_DRIVER INPUT_PSP
#elif defined(GEKKO)
#define INPUT_DEFAULT_DRIVER INPUT_WII
#elif defined(HAVE_UDEV)
#define INPUT_DEFAULT_DRIVER INPUT_UDEV
#elif defined(PANDORA) || defined(HAVE_VIDEOCORE)
#define INPUT_DEFAULT_DRIVER INPUT_LINUXRAW
#elif defined(HAVE_X11)

View File

@ -161,6 +161,9 @@ static const input_driver_t *input_drivers[] = {
#ifdef ANDROID
&input_android,
#endif
#ifdef HAVE_UDEV
&input_udev,
#endif
#if defined(__linux__) && !defined(ANDROID)
&input_linuxraw,
#endif

View File

@ -613,6 +613,7 @@ extern const input_driver_t input_xenon360;
extern const input_driver_t input_gx;
extern const input_driver_t input_xinput;
extern const input_driver_t input_linuxraw;
extern const input_driver_t input_udev;
extern const input_driver_t input_apple;
extern const input_driver_t input_qnx;
extern const input_driver_t input_rwebinput;

View File

@ -541,9 +541,14 @@ static void gfx_ctx_destroy(void)
static void gfx_ctx_input_driver(const input_driver_t **input, void **input_data)
{
void *xinput = input_udev.init();
*input = xinput ? &input_udev : NULL;
*input_data = xinput;
#if 0
void *xinput = input_x.init();
*input = xinput ? &input_x : NULL;
*input_data = xinput;
#endif
}
static bool gfx_ctx_has_focus(void)

View File

@ -38,6 +38,11 @@
#include <X11/keysym.h>
#endif
#ifdef __linux
#include <linux/input.h>
#include <linux/kd.h>
#endif
#include "../file.h"
static const rarch_joypad_driver_t *joypad_drivers[] = {
@ -624,6 +629,118 @@ const struct rarch_key_map rarch_key_map_rwebinput[] = {
};
#endif
#ifdef __linux
const struct rarch_key_map rarch_key_map_linux[] = {
{ KEY_ESC, RETROK_ESCAPE },
{ KEY_1, RETROK_1 },
{ KEY_2, RETROK_2 },
{ KEY_3, RETROK_3},
{ KEY_4, RETROK_4 },
{ KEY_5, RETROK_5 },
{ KEY_6, RETROK_6 },
{ KEY_7, RETROK_7 },
{ KEY_8, RETROK_8 },
{ KEY_9, RETROK_9 },
{ KEY_0, RETROK_0 },
{ KEY_MINUS, RETROK_MINUS },
{ KEY_EQUAL, RETROK_EQUALS },
{ KEY_BACKSPACE, RETROK_BACKSPACE },
{ KEY_TAB, RETROK_TAB },
{ KEY_Q, RETROK_q },
{ KEY_W, RETROK_w },
{ KEY_E, RETROK_e },
{ KEY_R, RETROK_r },
{ KEY_T, RETROK_t },
{ KEY_Y, RETROK_y },
{ KEY_U, RETROK_u },
{ KEY_I, RETROK_i },
{ KEY_O, RETROK_o },
{ KEY_P, RETROK_p },
{ KEY_LEFTBRACE, RETROK_LEFTBRACKET },
{ KEY_RIGHTBRACE, RETROK_RIGHTBRACKET },
{ KEY_ENTER, RETROK_RETURN },
{ KEY_LEFTCTRL, RETROK_LCTRL },
{ KEY_A, RETROK_a },
{ KEY_S, RETROK_s },
{ KEY_D, RETROK_d },
{ KEY_F, RETROK_f },
{ KEY_G, RETROK_g },
{ KEY_H, RETROK_h },
{ KEY_J, RETROK_j },
{ KEY_K, RETROK_k },
{ KEY_L, RETROK_l },
{ KEY_SEMICOLON, RETROK_SEMICOLON },
{ KEY_APOSTROPHE, RETROK_QUOTE },
{ KEY_GRAVE, RETROK_BACKQUOTE },
{ KEY_LEFTSHIFT, RETROK_LSHIFT },
{ KEY_BACKSLASH, RETROK_BACKSLASH },
{ KEY_Z, RETROK_z },
{ KEY_X, RETROK_x },
{ KEY_C, RETROK_c },
{ KEY_V, RETROK_v },
{ KEY_B, RETROK_b },
{ KEY_N, RETROK_n },
{ KEY_M, RETROK_m },
{ KEY_COMMA, RETROK_COMMA },
{ KEY_DOT, RETROK_PERIOD },
{ KEY_SLASH, RETROK_SLASH },
{ KEY_RIGHTSHIFT, RETROK_RSHIFT },
{ KEY_KPASTERISK, RETROK_KP_MULTIPLY },
{ KEY_LEFTALT, RETROK_LALT },
{ KEY_SPACE, RETROK_SPACE },
{ KEY_CAPSLOCK, RETROK_CAPSLOCK },
{ KEY_F1, RETROK_F1 },
{ KEY_F2, RETROK_F2 },
{ KEY_F3, RETROK_F3 },
{ KEY_F4, RETROK_F4 },
{ KEY_F5, RETROK_F5 },
{ KEY_F6, RETROK_F6 },
{ KEY_F7, RETROK_F7 },
{ KEY_F8, RETROK_F8 },
{ KEY_F9, RETROK_F9 },
{ KEY_F10, RETROK_F10 },
{ KEY_NUMLOCK, RETROK_NUMLOCK },
{ KEY_SCROLLLOCK, RETROK_SCROLLOCK },
{ KEY_KP7, RETROK_KP7 },
{ KEY_KP8, RETROK_KP8 },
{ KEY_KP9, RETROK_KP9 },
{ KEY_KPMINUS, RETROK_KP_MINUS },
{ KEY_KP4, RETROK_KP4 },
{ KEY_KP5, RETROK_KP5 },
{ KEY_KP6, RETROK_KP6 },
{ KEY_KPPLUS, RETROK_KP_PLUS },
{ KEY_KP1, RETROK_KP1 },
{ KEY_KP2, RETROK_KP2 },
{ KEY_KP3, RETROK_KP3 },
{ KEY_KP0, RETROK_KP0 },
{ KEY_KPDOT, RETROK_KP_PERIOD },
{ KEY_F11, RETROK_F11 },
{ KEY_F12, RETROK_F12 },
{ KEY_KPENTER, RETROK_KP_ENTER },
{ KEY_RIGHTCTRL, RETROK_RCTRL },
{ KEY_KPSLASH, RETROK_KP_DIVIDE },
{ KEY_SYSRQ, RETROK_PRINT },
{ KEY_RIGHTALT, RETROK_RALT },
{ KEY_HOME, RETROK_HOME },
{ KEY_UP, RETROK_UP },
{ KEY_PAGEUP, RETROK_PAGEUP },
{ KEY_LEFT, RETROK_LEFT },
{ KEY_RIGHT, RETROK_RIGHT },
{ KEY_END, RETROK_END },
{ KEY_DOWN, RETROK_DOWN },
{ KEY_PAGEDOWN, RETROK_PAGEDOWN },
{ KEY_INSERT, RETROK_INSERT },
{ KEY_DELETE, RETROK_DELETE },
{ KEY_PAUSE, RETROK_PAUSE },
};
#endif
static enum retro_key rarch_keysym_lut[RETROK_LAST];
void input_init_keyboard_lut(const struct rarch_key_map *map)

View File

@ -113,6 +113,7 @@ extern const struct rarch_key_map rarch_key_map_x11[];
extern const struct rarch_key_map rarch_key_map_sdl[];
extern const struct rarch_key_map rarch_key_map_dinput[];
extern const struct rarch_key_map rarch_key_map_rwebinput[];
extern const struct rarch_key_map rarch_key_map_linux[];
void input_init_keyboard_lut(const struct rarch_key_map *map);
enum retro_key input_translate_keysym_to_rk(unsigned sym);

View File

@ -35,129 +35,6 @@ typedef struct linuxraw_input
} linuxraw_input_t;
struct key_bind
{
uint8_t x;
enum retro_key sk;
};
static unsigned keysym_lut[RETROK_LAST];
static const struct key_bind lut_binds[] = {
{ KEY_ESC, RETROK_ESCAPE },
{ KEY_1, RETROK_1 },
{ KEY_2, RETROK_2 },
{ KEY_3, RETROK_3},
{ KEY_4, RETROK_4 },
{ KEY_5, RETROK_5 },
{ KEY_6, RETROK_6 },
{ KEY_7, RETROK_7 },
{ KEY_8, RETROK_8 },
{ KEY_9, RETROK_9 },
{ KEY_0, RETROK_0 },
{ KEY_MINUS, RETROK_MINUS },
{ KEY_EQUAL, RETROK_EQUALS },
{ KEY_BACKSPACE, RETROK_BACKSPACE },
{ KEY_TAB, RETROK_TAB },
{ KEY_Q, RETROK_q },
{ KEY_W, RETROK_w },
{ KEY_E, RETROK_e },
{ KEY_R, RETROK_r },
{ KEY_T, RETROK_t },
{ KEY_Y, RETROK_y },
{ KEY_U, RETROK_u },
{ KEY_I, RETROK_i },
{ KEY_O, RETROK_o },
{ KEY_P, RETROK_p },
{ KEY_LEFTBRACE, RETROK_LEFTBRACKET },
{ KEY_RIGHTBRACE, RETROK_RIGHTBRACKET },
{ KEY_ENTER, RETROK_RETURN },
{ KEY_LEFTCTRL, RETROK_LCTRL },
{ KEY_A, RETROK_a },
{ KEY_S, RETROK_s },
{ KEY_D, RETROK_d },
{ KEY_F, RETROK_f },
{ KEY_G, RETROK_g },
{ KEY_H, RETROK_h },
{ KEY_J, RETROK_j },
{ KEY_K, RETROK_k },
{ KEY_L, RETROK_l },
{ KEY_SEMICOLON, RETROK_SEMICOLON },
{ KEY_APOSTROPHE, RETROK_QUOTE },
{ KEY_GRAVE, RETROK_BACKQUOTE },
{ KEY_LEFTSHIFT, RETROK_LSHIFT },
{ KEY_BACKSLASH, RETROK_BACKSLASH },
{ KEY_Z, RETROK_z },
{ KEY_X, RETROK_x },
{ KEY_C, RETROK_c },
{ KEY_V, RETROK_v },
{ KEY_B, RETROK_b },
{ KEY_N, RETROK_n },
{ KEY_M, RETROK_m },
{ KEY_COMMA, RETROK_COMMA },
{ KEY_DOT, RETROK_PERIOD },
{ KEY_SLASH, RETROK_SLASH },
{ KEY_RIGHTSHIFT, RETROK_RSHIFT },
{ KEY_KPASTERISK, RETROK_KP_MULTIPLY },
{ KEY_LEFTALT, RETROK_LALT },
{ KEY_SPACE, RETROK_SPACE },
{ KEY_CAPSLOCK, RETROK_CAPSLOCK },
{ KEY_F1, RETROK_F1 },
{ KEY_F2, RETROK_F2 },
{ KEY_F3, RETROK_F3 },
{ KEY_F4, RETROK_F4 },
{ KEY_F5, RETROK_F5 },
{ KEY_F6, RETROK_F6 },
{ KEY_F7, RETROK_F7 },
{ KEY_F8, RETROK_F8 },
{ KEY_F9, RETROK_F9 },
{ KEY_F10, RETROK_F10 },
{ KEY_NUMLOCK, RETROK_NUMLOCK },
{ KEY_SCROLLLOCK, RETROK_SCROLLOCK },
{ KEY_KP7, RETROK_KP7 },
{ KEY_KP8, RETROK_KP8 },
{ KEY_KP9, RETROK_KP9 },
{ KEY_KPMINUS, RETROK_KP_MINUS },
{ KEY_KP4, RETROK_KP4 },
{ KEY_KP5, RETROK_KP5 },
{ KEY_KP6, RETROK_KP6 },
{ KEY_KPPLUS, RETROK_KP_PLUS },
{ KEY_KP1, RETROK_KP1 },
{ KEY_KP2, RETROK_KP2 },
{ KEY_KP3, RETROK_KP3 },
{ KEY_KP0, RETROK_KP0 },
{ KEY_KPDOT, RETROK_KP_PERIOD },
{ KEY_F11, RETROK_F11 },
{ KEY_F12, RETROK_F12 },
{ KEY_KPENTER, RETROK_KP_ENTER },
{ KEY_RIGHTCTRL, RETROK_RCTRL },
{ KEY_KPSLASH, RETROK_KP_DIVIDE },
{ KEY_SYSRQ, RETROK_PRINT },
{ KEY_RIGHTALT, RETROK_RALT },
{ KEY_HOME, RETROK_HOME },
{ KEY_UP, RETROK_UP },
{ KEY_PAGEUP, RETROK_PAGEUP },
{ KEY_LEFT, RETROK_LEFT },
{ KEY_RIGHT, RETROK_RIGHT },
{ KEY_END, RETROK_END },
{ KEY_DOWN, RETROK_DOWN },
{ KEY_PAGEDOWN, RETROK_PAGEDOWN },
{ KEY_INSERT, RETROK_INSERT },
{ KEY_DELETE, RETROK_DELETE },
{ KEY_PAUSE, RETROK_PAUSE },
};
static void init_lut(void)
{
unsigned i;
memset(keysym_lut, 0, sizeof(keysym_lut));
for (i = 0; i < ARRAY_SIZE(lut_binds); i++)
keysym_lut[lut_binds[i].sk] = lut_binds[i].x;
}
static void linuxraw_resetKbmd(void)
{
if (oldKbmd != 0xffff)
@ -232,7 +109,7 @@ static void *linuxraw_input_init(void)
atexit(linuxraw_resetKbmd);
linuxraw->joypad = input_joypad_init_driver(g_settings.input.joypad_driver);
init_lut();
input_init_keyboard_lut(rarch_key_map_linux);
driver.stdin_claimed = true; // We need to disable use of stdin command interface if stdin is supposed to be used for input.
return linuxraw;
@ -240,7 +117,8 @@ static void *linuxraw_input_init(void)
static bool linuxraw_key_pressed(linuxraw_input_t *linuxraw, int key)
{
return linuxraw->state[keysym_lut[key]];
unsigned sym = input_translate_rk_to_keysym((enum retro_key)key);
return linuxraw->state[sym];
}
static bool linuxraw_is_pressed(linuxraw_input_t *linuxraw, const struct retro_keybind *binds, unsigned id)
@ -346,6 +224,7 @@ static void linuxraw_input_poll(void *data)
static uint64_t linuxraw_get_capabilities(void *data)
{
(void)data;
uint64_t caps = 0;
caps |= (1 << RETRO_DEVICE_JOYPAD);

364
input/udev_input.c Normal file
View File

@ -0,0 +1,364 @@
/* RetroArch - A frontend for libretro.
* Copyright (C) 2010-2013 - Hans-Kristian Arntzen
*
* RetroArch is free software: you can redistribute it and/or modify it under the terms
* of the GNU General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with RetroArch.
* If not, see <http://www.gnu.org/licenses/>.
*/
#include "input_common.h"
#include "../general.h"
#include <unistd.h>
#include <stdint.h>
#include <string.h>
#include <limits.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/poll.h>
#include <fcntl.h>
#include <libudev.h>
#include <linux/types.h>
#include <linux/input.h>
typedef struct udev_input
{
const rarch_joypad_driver_t *joypad;
uint8_t key_state[(KEY_MAX + 7) / 8];
int keyboard_fd;
int mouse_fd;
int16_t mouse_x;
int16_t mouse_y;
bool mouse_l, mouse_r, mouse_m;
} udev_input_t;
static inline bool get_bit(const uint8_t *buf, unsigned bit)
{
return buf[bit >> 3] & (1 << (bit & 7));
}
static inline void clear_bit(uint8_t *buf, unsigned bit)
{
buf[bit >> 3] &= ~(1 << (bit & 7));
}
static inline void set_bit(uint8_t *buf, unsigned bit)
{
buf[bit >> 3] |= 1 << (bit & 7);
}
static void udev_input_poll(void *data)
{
udev_input_t *udev = (udev_input_t*)data;
if (udev->keyboard_fd >= 0)
{
int i, len;
struct input_event events[32];
while ((len = read(udev->keyboard_fd, events, sizeof(events))) > 0)
{
len /= sizeof(*events);
for (i = 0; i < len; i++)
{
switch (events[i].type)
{
case EV_KEY:
if (events[i].value)
set_bit(udev->key_state, events[i].code);
else
clear_bit(udev->key_state, events[i].code);
break;
default:
break;
}
}
}
}
if (udev->mouse_fd >= 0)
{
udev->mouse_x = udev->mouse_y = 0;
int i, len;
struct input_event events[32];
while ((len = read(udev->keyboard_fd, events, sizeof(events))) > 0)
{
len /= sizeof(*events);
for (i = 0; i < len; i++)
{
switch (events[i].type)
{
case EV_KEY:
switch (events[i].code)
{
case BTN_LEFT:
udev->mouse_l = events[i].value;
break;
case BTN_RIGHT:
udev->mouse_r = events[i].value;
break;
case BTN_MIDDLE:
udev->mouse_m = events[i].value;
break;
default:
break;
}
break;
case EV_REL:
switch (events[i].code)
{
case REL_X:
udev->mouse_x += events[i].value;
break;
case REL_Y:
udev->mouse_y += events[i].value;
break;
default:
break;
}
break;
default:
break;
}
}
}
}
input_joypad_poll(udev->joypad);
}
static int16_t udev_mouse_state(udev_input_t *udev, unsigned id)
{
switch (id)
{
case RETRO_DEVICE_ID_MOUSE_X:
return udev->mouse_x;
case RETRO_DEVICE_ID_MOUSE_Y:
return udev->mouse_y;
case RETRO_DEVICE_ID_MOUSE_LEFT:
return udev->mouse_l;
case RETRO_DEVICE_ID_MOUSE_RIGHT:
return udev->mouse_r;
default:
return 0;
}
}
static int16_t udev_lightgun_state(udev_input_t *udev, unsigned id)
{
switch (id)
{
case RETRO_DEVICE_ID_LIGHTGUN_X:
return udev->mouse_x;
case RETRO_DEVICE_ID_LIGHTGUN_Y:
return udev->mouse_y;
case RETRO_DEVICE_ID_LIGHTGUN_TRIGGER:
return udev->mouse_l;
case RETRO_DEVICE_ID_LIGHTGUN_CURSOR:
return udev->mouse_m;
case RETRO_DEVICE_ID_LIGHTGUN_TURBO:
return udev->mouse_r;
case RETRO_DEVICE_ID_LIGHTGUN_START:
return udev->mouse_m && udev->mouse_r;
case RETRO_DEVICE_ID_LIGHTGUN_PAUSE:
return udev->mouse_m && udev->mouse_l;
default:
return 0;
}
}
static bool udev_is_pressed(udev_input_t *udev, const struct retro_keybind *binds, unsigned id)
{
if (id < RARCH_BIND_LIST_END)
{
const struct retro_keybind *bind = &binds[id];
return bind->valid && get_bit(udev->key_state, input_translate_rk_to_keysym(binds[id].key));
}
else
return false;
}
static int16_t udev_analog_pressed(udev_input_t *udev,
const struct retro_keybind *binds, unsigned index, unsigned id)
{
unsigned id_minus = 0;
unsigned id_plus = 0;
input_conv_analog_id_to_bind_id(index, id, &id_minus, &id_plus);
int16_t pressed_minus = udev_is_pressed(udev,
binds, id_minus) ? -0x7fff : 0;
int16_t pressed_plus = udev_is_pressed(udev,
binds, id_plus) ? 0x7fff : 0;
return pressed_plus + pressed_minus;
}
static int16_t udev_input_state(void *data, const struct retro_keybind **binds,
unsigned port, unsigned device, unsigned index, unsigned id)
{
udev_input_t *udev = (udev_input_t*)data;
int16_t ret;
switch (device)
{
case RETRO_DEVICE_JOYPAD:
return udev_is_pressed(udev, binds[port], id) ||
input_joypad_pressed(udev->joypad, port, binds[port], id);
case RETRO_DEVICE_ANALOG:
ret = udev_analog_pressed(udev, binds[port], index, id);
if (!ret)
ret = input_joypad_analog(udev->joypad, port, index, id, binds[port]);
return ret;
case RETRO_DEVICE_KEYBOARD:
return id < RETROK_LAST && get_bit(udev->key_state, input_translate_rk_to_keysym(id));
case RETRO_DEVICE_MOUSE:
return udev_mouse_state(udev, id);
case RETRO_DEVICE_LIGHTGUN:
return udev_lightgun_state(udev, id);
default:
return 0;
}
}
static bool udev_bind_button_pressed(void *data, int key)
{
udev_input_t *udev = (udev_input_t*)data;
return udev_is_pressed(udev, g_settings.input.binds[0], key) ||
input_joypad_pressed(udev->joypad, 0, g_settings.input.binds[0], key);
}
static void udev_input_free(void *data)
{
udev_input_t *udev = (udev_input_t*)data;
if (udev->joypad)
udev->joypad->destroy();
if (udev->keyboard_fd >= 0)
close(udev->keyboard_fd);
if (udev->mouse_fd >= 0)
close(udev->mouse_fd);
free(udev);
}
static int open_device(const char *type)
{
int ret = -1;
struct udev_list_entry *devs = NULL;
struct udev_list_entry *item = NULL;
struct udev *udev = udev_new();
if (!udev)
return ret;
struct udev_enumerate *enumerate = udev_enumerate_new(udev);
if (!enumerate)
{
udev_unref(udev);
return ret;
}
udev_enumerate_add_match_property(enumerate, type, "1");
udev_enumerate_scan_devices(enumerate);
devs = udev_enumerate_get_list_entry(enumerate);
for (item = devs; item; item = udev_list_entry_get_next(item))
{
const char *name = udev_list_entry_get_name(item);
struct udev_device *dev = udev_device_new_from_syspath(udev, name);
const char *devnode = udev_device_get_devnode(dev);
int fd = devnode ? open(devnode, O_RDONLY | O_NONBLOCK) : -1;
udev_device_unref(dev);
if (fd >= 0)
{
ret = fd;
break;
}
}
udev_enumerate_unref(enumerate);
udev_unref(udev);
return ret;
}
static void *udev_input_init(void)
{
udev_input_t *udev = (udev_input_t*)calloc(1, sizeof(*udev));
if (!udev)
return NULL;
udev->keyboard_fd = open_device("ID_INPUT_KEYBOARD");
udev->mouse_fd = open_device("ID_INPUT_MOUSE");
if (udev->keyboard_fd < 0)
RARCH_WARN("Failed to find a keyboard.\n");
if (udev->mouse_fd < 0)
RARCH_WARN("Failed to find a mouse.\n");
udev->joypad = input_joypad_init_driver(g_settings.input.joypad_driver);
input_init_keyboard_lut(rarch_key_map_linux);
return udev;
}
static uint64_t udev_input_get_capabilities(void *data)
{
(void)data;
return
(1 << RETRO_DEVICE_JOYPAD) |
(1 << RETRO_DEVICE_ANALOG) |
(1 << RETRO_DEVICE_KEYBOARD) |
(1 << RETRO_DEVICE_MOUSE) |
(1 << RETRO_DEVICE_LIGHTGUN);
}
static bool udev_input_set_rumble(void *data, unsigned port, enum retro_rumble_effect effect, uint16_t strength)
{
udev_input_t *udev = (udev_input_t*)data;
return input_joypad_set_rumble(udev->joypad, port, effect, strength);
}
static const rarch_joypad_driver_t *udev_input_get_joypad_driver(void *data)
{
udev_input_t *udev = (udev_input_t*)data;
return udev->joypad;
}
const input_driver_t input_udev = {
udev_input_init,
udev_input_poll,
udev_input_state,
udev_bind_button_pressed,
udev_input_free,
NULL,
NULL,
udev_input_get_capabilities,
"udev",
NULL,
udev_input_set_rumble,
udev_input_get_joypad_driver,
};

View File

@ -253,77 +253,6 @@ static void udev_joypad_poll(void)
(((1UL << ((nr) % (sizeof(long) * CHAR_BIT))) & ((addr)[(nr) / (sizeof(long) * CHAR_BIT)])) != 0)
#define NBITS(x) ((((x) - 1) / (sizeof(long) * CHAR_BIT)) + 1)
#if 0
static void test_initial_rumble(int fd, const char *path)
{
// Check for rumble features.
unsigned long ffbit[NBITS(FF_MAX)] = {0};
if (ioctl(fd, EVIOCGBIT(EV_FF, sizeof(ffbit)), ffbit) >= 0)
{
if (test_bit(FF_RUMBLE, ffbit))
RARCH_LOG("[udev]: Pad (%s) supports force feedback.\n",
path);
int effects;
if (ioctl(fd, EVIOCGEFFECTS, &effects) >= 0)
RARCH_LOG("[udev]: Pad (%s) supports %d force feedback effects.\n", path, effects);
if (effects >= 2)
{
struct ff_effect effect;
bool support_ff[2];
int effects[2] = {-1, -1};
// Strong rumble.
memset(&effect, 0, sizeof(effect));
effect.type = FF_RUMBLE;
effect.id = -1;
effect.u.rumble.strong_magnitude = 0x8000;
effect.u.rumble.weak_magnitude = 0;
support_ff[0] = ioctl(fd, EVIOCSFF, &effect) == 0;
if (support_ff[0])
{
RARCH_LOG("[udev]: (%s) supports \"strong\" rumble effect (id %d).\n",
path, effect.id);
effects[RETRO_RUMBLE_STRONG] = effect.id; // Gets updated by ioctl().
}
// Weak rumble.
memset(&effect, 0, sizeof(effect));
effect.type = FF_RUMBLE;
effect.id = -1;
effect.u.rumble.strong_magnitude = 0;
effect.u.rumble.weak_magnitude = 0xc000;
support_ff[1] = ioctl(fd, EVIOCSFF, &effect) == 0;
if (support_ff[1])
{
RARCH_LOG("[udev]: Pad (%s) supports \"weak\" rumble effect (id %d).\n",
path, effect.id);
effects[RETRO_RUMBLE_WEAK] = effect.id;
}
struct input_event play;
memset(&play, 0, sizeof(play));
play.type = EV_FF;
play.code = effects[0];
play.value = true;
write(fd, &play, sizeof(play));
rarch_sleep(500);
play.value = false;
write(fd, &play, sizeof(play));
rarch_sleep(500);
play.code = effects[1];
play.value = true;
write(fd, &play, sizeof(play));
rarch_sleep(500);
play.value = false;
write(fd, &play, sizeof(play));
}
}
}
#endif
static int open_joystick(const char *path)
{
int fd = open(path, O_RDWR | O_NONBLOCK);