Added "rel-repeat", which allows to have the stick not modify the value, but the repeat rate of REL events

This commit is contained in:
Ingo Ruhnke 2011-03-10 12:29:35 +01:00
parent fcdd07b570
commit 6d18897f12
3 changed files with 121 additions and 2 deletions

View file

@ -14,8 +14,13 @@ ui-clear=true
[ui-axismap]
x1^dead:4000 = REL_X:750:-1
y1^dead:4000 = REL_Y:750:-1
y2^dead:6000^invert = REL_WHEEL:5:100
x2^dead:6000 = REL_HWHEEL:5:100
# y2^dead:6000^invert = REL_WHEEL:5:100
# x2^dead:6000 = REL_HWHEEL:5:100
y2^dead:6000^invert = rel-repeat:REL_WHEEL:1:50
x2^dead:6000 = rel-repeat:REL_HWHEEL:1:50
trigger^invert=REL_WHEEL:5:100
[ui-buttonmap]

View file

@ -22,6 +22,7 @@
#include "evdev_helper.hpp"
#include "log.hpp"
#include "raise_exception.hpp"
#include "uinput.hpp"
AxisEventPtr
@ -64,6 +65,10 @@ AxisEvent::from_string(const std::string& str)
{
ev.reset(new AxisEvent(RelAxisEventHandler::from_string(rest)));
}
else if (token == "rel-repeat")
{
ev.reset(new AxisEvent(RelRepeatAxisEventHandler::from_string(rest)));
}
else if (token == "key")
{
ev.reset(new AxisEvent(KeyAxisEventHandler::from_string(rest)));
@ -283,6 +288,92 @@ RelAxisEventHandler::str() const
return out.str();
}
RelRepeatAxisEventHandler*
RelRepeatAxisEventHandler::from_string(const std::string& str)
{
// split string at ':'
boost::tokenizer<boost::char_separator<char> >
tokens(str, boost::char_separator<char>(":", "", boost::keep_empty_tokens));
std::vector<std::string> args;
std::copy(tokens.begin(), tokens.end(), std::back_inserter(args));
if (args.size() == 3)
{
return new RelRepeatAxisEventHandler(str2rel_event(args[0]),
boost::lexical_cast<int>(args[1]),
boost::lexical_cast<float>(args[2]));
}
else
{
raise_exception(std::runtime_error, "must have three arguments");
}
}
RelRepeatAxisEventHandler::RelRepeatAxisEventHandler(const UIEvent& code, int value, int repeat) :
m_code(code),
m_value(value),
m_repeat(repeat),
m_stick_value(0),
m_timer(0)
{
}
void
RelRepeatAxisEventHandler::init(UInput& uinput, int slot, bool extra_devices)
{
m_code.resolve_device_id(slot, extra_devices);
uinput.add_rel(m_code.get_device_id(), m_code.code);
}
void
RelRepeatAxisEventHandler::send(UInput& uinput, int value)
{
if (value < 0)
{
m_stick_value = value / static_cast<float>(-m_min);
}
else
{
m_stick_value = value / static_cast<float>(m_max);
}
// reset timer when in center position
if (value == 0)
{
m_timer = 0;
}
}
void
RelRepeatAxisEventHandler::update(UInput& uinput, int msec_delta)
{
// time ticks slower depending on how fr the stick is moved
m_timer += msec_delta * fabsf(m_stick_value);
while(m_timer > m_repeat)
{
if (m_stick_value < 0)
{
uinput.send_rel(m_code.get_device_id(), m_code.code, -m_value);
}
else
{
uinput.send_rel(m_code.get_device_id(), m_code.code, m_value);
}
m_timer -= m_repeat;
}
}
std::string
RelRepeatAxisEventHandler::str() const
{
std::ostringstream out;
out << "rel-repeat:" << m_value << ":" << m_repeat;
return out.str();
}
AbsAxisEventHandler*
AbsAxisEventHandler::from_string(const std::string& str)
{

View file

@ -107,6 +107,29 @@ private:
float m_rest_value;
};
class RelRepeatAxisEventHandler : public AxisEventHandler
{
public:
static RelRepeatAxisEventHandler* from_string(const std::string& str);
public:
RelRepeatAxisEventHandler(const UIEvent& code, int value, int repeat);
void init(UInput& uinput, int slot, bool extra_devices);
void send(UInput& uinput, int value);
void update(UInput& uinput, int msec_delta);
std::string str() const;
private:
UIEvent m_code;
int m_value;
float m_repeat;
float m_stick_value;
int m_timer;
};
class AbsAxisEventHandler : public AxisEventHandler
{
public: