Added ExecButtonHandler

This commit is contained in:
Ingo Ruhnke 2010-12-29 17:46:41 +01:00
parent e6b1328174
commit 0304f7b384
4 changed files with 122 additions and 9 deletions

25
TODO
View file

@ -27,6 +27,31 @@ $ dput my-ppa xboxdrv_0.6.1_source.changes
Stuff to do before 0.6.1 release:
=================================
* split by "," should ignore empty fields
* support for macros:
--ui-buttonevent A=macro:file.macro
syntax:
send KEY_A 0
send ABS_X 25
wait 10
send ABS_X 24
* support for programs:
--ui-buttonevent A=exec:/usr/bin/foo
* convert --mouse to use the new input filter
* give some response curve examples:
# Low sensitivity on the stick when LB is pressed:
--ui-axismap lb+y1^resp:-8000:0:8000=ABS_Y,y1=ABS_Y,lb+x1^resp:-8000:0:8000=ABS_X,x1=ABS_X
* figure out how to do absolute mouse positioning in Xorg
* AxisFilter: invert(*), sensitivy(*), deadzone(*), relative-axis(*)

View file

@ -17,12 +17,15 @@
*/
#include <assert.h>
#include <boost/lexical_cast.hpp>
#include <boost/tokenizer.hpp>
#include <errno.h>
#include <iostream>
#include <linux/input.h>
#include <stdexcept>
#include <memory>
#include <boost/tokenizer.hpp>
#include <boost/lexical_cast.hpp>
#include <stdexcept>
#include <string.h>
#include <unistd.h>
#include "helper.hpp"
#include "button_event.hpp"
@ -71,18 +74,26 @@ ButtonEvent::from_string(const std::string& str)
{
std::string::size_type p = str.find(':');
const std::string& token = str.substr(0, p);
std::string rest;
if (p != std::string::npos)
rest = str.substr(p+1);
if (token == "abs")
{
return ButtonEvent::create(AbsButtonEventHandler::from_string(str.substr(p+1)));
return ButtonEvent::create(AbsButtonEventHandler::from_string(rest));
}
else if (token == "rel")
{
return ButtonEvent::create(RelButtonEventHandler::from_string(str.substr(p+1)));
return ButtonEvent::create(RelButtonEventHandler::from_string(rest));
}
else if (token == "key")
{
return ButtonEvent::create(KeyButtonEventHandler::from_string(str.substr(p+1)));
return ButtonEvent::create(KeyButtonEventHandler::from_string(rest));
}
else if (token == "exec")
{
return ButtonEvent::create(ExecButtonEventHandler::from_string(rest));
}
else
{
@ -92,7 +103,7 @@ ButtonEvent::from_string(const std::string& str)
case EV_KEY: return ButtonEvent::create(KeyButtonEventHandler::from_string(str));
case EV_REL: return ButtonEvent::create(RelButtonEventHandler::from_string(str));
case EV_ABS: return ButtonEvent::create(AbsButtonEventHandler::from_string(str));
case -1: return ButtonEventPtr();
case -1: return ButtonEvent::invalid();
default: assert(!"unknown type");
}
}
@ -172,7 +183,6 @@ KeyButtonEventHandler::from_string(const std::string& str)
int idx = 0;
for(tokenizer::iterator i = tokens.begin(); i != tokens.end(); ++i, ++idx)
{
switch(idx)
{
case 0:
@ -462,4 +472,62 @@ RelButtonEventHandler::str() const
return out.str();
}
ExecButtonEventHandler*
ExecButtonEventHandler::from_string(const std::string& str)
{
std::vector<std::string> args;
typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
tokenizer tokens(str, boost::char_separator<char>(":", "", boost::keep_empty_tokens));
std::copy(tokens.begin(), tokens.end(), std::back_inserter(args));
return new ExecButtonEventHandler(args);
}
ExecButtonEventHandler::ExecButtonEventHandler(const std::vector<std::string>& args) :
m_args(args)
{
}
void
ExecButtonEventHandler::init(uInput& uinput) const
{
// nothing to do
}
void
ExecButtonEventHandler::send(uInput& uinput, bool value)
{
if (value)
{
pid_t pid = fork();
if (pid == 0)
{
char** argv = static_cast<char**>(malloc(sizeof(char*) * m_args.size()));
for(size_t i = 0; i < m_args.size(); ++i)
{
argv[i] = strdup(m_args[i].c_str());
}
if (execvp(m_args[0].c_str(), argv) == -1)
{
std::cout << "error: ExecButtonEventHandler::send(): " << strerror(errno) << std::endl;
}
for(size_t i = 0; i < m_args.size(); ++i)
{
free(argv[i]);
}
free(argv);
}
}
}
std::string
ExecButtonEventHandler::str() const
{
return "exec";
}
/* EOF */

View file

@ -139,6 +139,24 @@ private:
int m_repeat;
};
class ExecButtonEventHandler : public ButtonEventHandler
{
public:
static ExecButtonEventHandler* from_string(const std::string& str);
public:
ExecButtonEventHandler(const std::vector<std::string>& args);
void init(uInput& uinput) const;
void send(uInput& uinput, bool value);
void update(uInput& uinput, int msec_delta) {}
std::string str() const;
private:
std::vector<std::string> m_args;
};
#endif
/* EOF */

View file

@ -742,7 +742,9 @@ CommandLineParser::set_ui_buttonmap(const std::string& name, const std::string&
std::string btn_str = lhs;
ButtonEventPtr event = ButtonEvent::from_string(value);
event->set_filters(filters);
if (event)
event->set_filters(filters);
std::string::size_type j = btn_str.find('+');
if (j == std::string::npos)