Implemented --ui-buttonmap A=BTN_A@{device_id}

This commit is contained in:
Ingo Ruhnke 2010-05-19 15:54:02 +02:00
parent 197a0ad9f3
commit be705c856e
7 changed files with 214 additions and 31 deletions

View file

@ -23,11 +23,13 @@
#include "axis_event.hpp"
#include "evdev_helper.hpp"
#include "uinput_deviceid.hpp"
AxisEvent
AxisEvent::create(int type, int code, int fuzz, int flat)
{
AxisEvent ev;
ev.device_id = DEVICEID_AUTO;
ev.type = type;
ev.code = code;
@ -74,8 +76,11 @@ AxisEvent::from_string(const std::string& str)
{
if (j == 0)
{
std::string event_str;
split_event_name(*i, &event_str, &ev.device_id);
int type, code;
if (!str2event(*i, type, code))
if (!str2event(event_str, type, code))
{
throw std::runtime_error("Couldn't convert '" + str + "' to AxisEvent");
}
@ -117,4 +122,10 @@ AxisEvent::from_string(const std::string& str)
return ev;
}
bool
AxisEvent::is_valid() const
{
return device_id != DEVICEID_INVALID && type != -1 && code != -1;
}
/* EOF */

View file

@ -27,6 +27,8 @@ struct AxisEvent
static AxisEvent create(int type, int code, int fuzz = 0, int flat = 0);
static AxisEvent from_string(const std::string& str);
int device_id;
/** EV_KEY, EV_ABS, EV_REL */
int type;
@ -49,6 +51,8 @@ struct AxisEvent
int threshold;
} key;
};
bool is_valid() const;
};
#endif

View file

@ -24,11 +24,20 @@
#include "button_event.hpp"
#include "evdev_helper.hpp"
#include "uinput_deviceid.hpp"
ButtonEvent
ButtonEvent::create(int type, int code)
{
return ButtonEvent::create(DEVICEID_AUTO, type, code);
}
ButtonEvent
ButtonEvent::create(int device_id, int type, int code)
{
ButtonEvent ev;
ev.device_id = device_id;
ev.type = type;
ev.code = code;
@ -70,14 +79,18 @@ ButtonEvent::from_string(const std::string& str)
{
if (j == 0)
{
std::string event_str;
split_event_name(*i, &event_str, &ev.device_id);
int type, code;
if (!str2event(*i, type, code))
if (!str2event(event_str, type, code))
{
throw std::runtime_error("Couldn't convert '" + str + "' to ButtonEvent");
}
else
{
ev = ButtonEvent::create(type, code);
// create the event via function call to get proper default values
ev = ButtonEvent::create(ev.device_id, type, code);
}
}
else
@ -97,4 +110,10 @@ ButtonEvent::from_string(const std::string& str)
return ev;
}
bool
ButtonEvent::is_valid() const
{
return device_id != DEVICEID_INVALID && type != -1 && code != -1;
}
/* EOF */

View file

@ -21,12 +21,17 @@
#include <string>
#include "uinput_deviceid.hpp"
struct ButtonEvent
{
static ButtonEvent invalid() { return create(-1, -1); }
static ButtonEvent invalid() { return create(DEVICEID_INVALID, -1, -1); }
static ButtonEvent create(int device_id, int type, int code);
static ButtonEvent create(int type, int code);
static ButtonEvent from_string(const std::string& str);
int device_id;
/** EV_KEY, EV_ABS, EV_REL */
int type;
@ -46,6 +51,8 @@ struct ButtonEvent
struct {
} key;
};
bool is_valid() const;
};
#endif

View file

@ -31,6 +31,7 @@
#include "xboxmsg.hpp"
#include "uinput.hpp"
#include "uinput_deviceid.hpp"
bool
uInput::need_keyboard_device()
@ -110,9 +111,8 @@ uInput::is_keyboard_button(int ev_code)
}
uInput::uInput(const XPadDevice& dev, uInputCfg config_) :
joystick_uinput_dev(),
keyboard_uinput_dev(),
mouse_uinput_dev(),
m_dev(dev),
uinput_devs(),
cfg(config_),
rel_axis(),
rel_button()
@ -120,6 +120,22 @@ uInput::uInput(const XPadDevice& dev, uInputCfg config_) :
std::fill_n(axis_state, static_cast<int>(XBOX_AXIS_MAX), 0);
std::fill_n(button_state, static_cast<int>(XBOX_BTN_MAX), false);
if (cfg.force_feedback)
{
create_uinput_device(0);
}
for(int i = 0; i < XBOX_BTN_MAX; ++i)
{
create_uinput_device(cfg.btn_map[i]);
}
for(int i = 0; i < XBOX_AXIS_MAX; ++i)
{
create_uinput_device(cfg.axis_map[i]);
}
/*
joystick_uinput_dev = std::auto_ptr<LinuxUinput>(new LinuxUinput(cfg.device_name, dev.idVendor, dev.idProduct));
if (cfg.extra_devices && need_mouse_device())
@ -131,6 +147,7 @@ uInput::uInput(const XPadDevice& dev, uInputCfg config_) :
{
keyboard_uinput_dev = std::auto_ptr<LinuxUinput>(new LinuxUinput(cfg.device_name + " - Keyboard Emulation", dev.idVendor, dev.idProduct));
}
*/
switch(dev.type)
{
@ -152,10 +169,117 @@ uInput::uInput(const XPadDevice& dev, uInputCfg config_) :
break;
}
joystick_uinput_dev->finish();
for(uInputDevs::iterator i = uinput_devs.begin(); i != uinput_devs.end(); ++i)
{
i->second->finish();
}
}
if (keyboard_uinput_dev.get()) keyboard_uinput_dev->finish();
if (mouse_uinput_dev.get()) mouse_uinput_dev->finish();
void
uInput::create_uinput_device(int device_id)
{
uInputDevs::iterator it = uinput_devs.find(device_id);
if (it != uinput_devs.end())
{
// device already exist, which is fine
}
else
{
std::ostringstream dev_name;
dev_name << cfg.device_name;
if (device_id == DEVICEID_MOUSE)
{
dev_name << " - Mouse Emulation";
}
else if (device_id == DEVICEID_KEYBOARD)
{
dev_name << " - Keyboard Emulation";
}
else if (dev_name > 0)
{
dev_name << " - Joystick " << device_id+1;
}
boost::shared_ptr<LinuxUinput> dev(new LinuxUinput(dev_name.str(), m_dev.idVendor, m_dev.idProduct));
uinput_devs.insert(std::pair<int, boost::shared_ptr<LinuxUinput> >(device_id, dev));
}
}
void
uInput::create_uinput_device(const AxisEvent& event)
{
if (event.is_valid())
{
if (event.device_id == DEVICEID_AUTO)
{
if (event.type == EV_KEY)
{
if (is_mouse_button(event.code) || is_mouse_button(event.key.secondary_code))
{
create_uinput_device(DEVICEID_MOUSE);
}
else if (is_keyboard_button(event.code) || is_keyboard_button(event.key.secondary_code))
{
create_uinput_device(DEVICEID_KEYBOARD);
}
else
{
create_uinput_device(DEVICEID_JOYSTICK);
}
}
else if (event.type == EV_REL)
{
create_uinput_device(DEVICEID_MOUSE);
}
else
{
create_uinput_device(DEVICEID_JOYSTICK);
}
}
else
{
create_uinput_device(event.device_id);
}
}
}
void
uInput::create_uinput_device(const ButtonEvent& event)
{
if (event.is_valid())
{
if (event.device_id == DEVICEID_AUTO)
{
if (event.type == EV_KEY)
{
if (is_mouse_button(event.code))
{
create_uinput_device(DEVICEID_MOUSE);
}
else if (is_keyboard_button(event.code))
{
create_uinput_device(DEVICEID_KEYBOARD);
}
else
{
create_uinput_device(DEVICEID_JOYSTICK);
}
}
else if (event.type == EV_REL)
{
create_uinput_device(DEVICEID_MOUSE);
}
else
{
create_uinput_device(DEVICEID_JOYSTICK);
}
}
else
{
create_uinput_device(event.device_id);
}
}
}
void
@ -548,7 +672,7 @@ uInput::send_button(int code, bool value)
}
void
uInput::add_key(int ev_code)
uInput::add_key(int device_id, int ev_code)
{
if (is_keyboard_button(ev_code))
get_keyboard_uinput()->add_key(ev_code);
@ -656,9 +780,9 @@ uInput::add_axis(int code, int min, int max)
break;
case EV_KEY:
add_key(event.code);
add_key(event.device_id, event.code);
if (event.code != event.key.secondary_code)
add_key(event.key.secondary_code);
add_key(event.device_id, event.key.secondary_code);
break;
case -1:
@ -677,7 +801,7 @@ uInput::add_button(int code)
if (event.type == EV_KEY)
{
add_key(event.code);
add_key(event.device_id, event.code);
}
else if (event.type == EV_REL)
{
@ -694,28 +818,38 @@ uInput::add_button(int code)
}
}
LinuxUinput*
uInput::get_uinput(int device_id) const
{
uInputDevs::const_iterator it = uinput_devs.find(device_id);
if (it != uinput_devs.end())
{
return it->second.get();
}
else
{
std::ostringstream str;
str << "Couldn't find uinput device: " << device_id;
throw std::runtime_error(str.str());
}
}
LinuxUinput*
uInput::get_mouse_uinput() const
{
if (mouse_uinput_dev.get())
return mouse_uinput_dev.get();
else
return joystick_uinput_dev.get();
return get_uinput(DEVICEID_MOUSE);
}
LinuxUinput*
uInput::get_keyboard_uinput() const
{
if (keyboard_uinput_dev.get())
return keyboard_uinput_dev.get();
else
return joystick_uinput_dev.get();
return get_uinput(DEVICEID_KEYBOARD);
}
LinuxUinput*
uInput::get_joystick_uinput() const
{
return joystick_uinput_dev.get();
return get_uinput(0);
}
void

View file

@ -20,8 +20,10 @@
#define HEADER_UINPUT_HPP
#include <vector>
#include <map>
#include <memory>
#include <stdexcept>
#include <boost/shared_ptr.hpp>
#include "axis_event.hpp"
#include "button_event.hpp"
@ -38,9 +40,10 @@ class XboxMsg;
class uInput
{
private:
std::auto_ptr<LinuxUinput> joystick_uinput_dev;
std::auto_ptr<LinuxUinput> keyboard_uinput_dev;
std::auto_ptr<LinuxUinput> mouse_uinput_dev;
XPadDevice m_dev;
typedef std::map<int, boost::shared_ptr<LinuxUinput> > uInputDevs;
uInputDevs uinput_devs;
uInputCfg cfg;
int axis_state[XBOX_AXIS_MAX];
@ -81,16 +84,21 @@ private:
void add_axis(int code, int min, int max);
void add_button(int code);
void add_key(int ev_code);
void send_key(int ev_code, bool value);
void send_button(int code, bool value);
void send_axis(int code, int32_t value);
void add_key(int device_id, int ev_code);
void send_key(int ev_code, bool value);
LinuxUinput* get_uinput(int device_id) const;
LinuxUinput* get_mouse_uinput() const;
LinuxUinput* get_keyboard_uinput() const;
LinuxUinput* get_joystick_uinput() const;
void create_uinput_device(int device_id);
void create_uinput_device(const AxisEvent& event);
void create_uinput_device(const ButtonEvent& event);
bool need_mouse_device();
bool need_keyboard_device();
bool need_joystick_device();

View file

@ -29,8 +29,8 @@ uInputCfg::uInputCfg() :
force_feedback(false),
extra_devices(true)
{
std::fill_n(btn_map, static_cast<int>(XBOX_BTN_MAX), ButtonEvent::create(-1, -1));
std::fill_n(axis_map, static_cast<int>(XBOX_AXIS_MAX), AxisEvent::create(-1, -1));
std::fill_n(btn_map, static_cast<int>(XBOX_BTN_MAX), ButtonEvent::invalid());
std::fill_n(axis_map, static_cast<int>(XBOX_AXIS_MAX), AxisEvent::invalid());
// Button Mapping
btn_map[XBOX_BTN_START] = ButtonEvent::create(EV_KEY, BTN_START);