Added some upport for rel events
This commit is contained in:
parent
74f8aa534f
commit
2719b3105e
8 changed files with 234 additions and 19 deletions
|
@ -6,6 +6,7 @@ env.Program("inputdrv",
|
|||
["inputdrv.cpp",
|
||||
"xbox360_driver.cpp",
|
||||
"control.cpp",
|
||||
"abs_to_rel.cpp",
|
||||
"uinput_driver.cpp",
|
||||
"toggle_button.cpp"],
|
||||
LIBS=['boost_signals', 'usb'])
|
||||
|
|
42
abs_to_rel.cpp
Normal file
42
abs_to_rel.cpp
Normal file
|
@ -0,0 +1,42 @@
|
|||
/* $Id$
|
||||
** __ __ __ ___ __ __ __ __
|
||||
** / \ / \__| ____ __| _/_______/ |_|__| | | | ____
|
||||
** \ \/\/ / |/ \ / __ |/ ___/\ __\ | | | | _/ __ \
|
||||
** \ /| | | \/ /_/ |\___ \ | | | | |_| |_\ ___/
|
||||
** \__/\ / |__|___| /\____ /____ > |__| |__|____/____/\___ >
|
||||
** \/ \/ \/ \/ \/
|
||||
** Copyright (C) 2007 Ingo Ruhnke <grumbel@gmx.de>
|
||||
**
|
||||
** This program 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 Foundation; either version 2
|
||||
** of the License, or (at your option) any later version.
|
||||
**
|
||||
** This program 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 this program; if not, write to the Free Software
|
||||
** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
** 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include <boost/bind.hpp>
|
||||
#include "abs_to_rel.hpp"
|
||||
|
||||
AbsToRel::AbsToRel()
|
||||
{
|
||||
abs_port_in.push_back(new AbsPortIn("AbsToRel-In", 0, 0,
|
||||
boost::bind(&AbsToRel::on_abs, this, _1)));
|
||||
rel_port_out.push_back(new RelPortOut("AbsToRel-Out"));
|
||||
}
|
||||
|
||||
void
|
||||
AbsToRel::on_abs(AbsPortOut* port)
|
||||
{
|
||||
rel_port_out[0]->set_state(port->get_state());
|
||||
}
|
||||
|
||||
/* EOF */
|
47
abs_to_rel.hpp
Normal file
47
abs_to_rel.hpp
Normal file
|
@ -0,0 +1,47 @@
|
|||
/* $Id$
|
||||
** __ __ __ ___ __ __ __ __
|
||||
** / \ / \__| ____ __| _/_______/ |_|__| | | | ____
|
||||
** \ \/\/ / |/ \ / __ |/ ___/\ __\ | | | | _/ __ \
|
||||
** \ /| | | \/ /_/ |\___ \ | | | | |_| |_\ ___/
|
||||
** \__/\ / |__|___| /\____ /____ > |__| |__|____/____/\___ >
|
||||
** \/ \/ \/ \/ \/
|
||||
** Copyright (C) 2007 Ingo Ruhnke <grumbel@gmx.de>
|
||||
**
|
||||
** This program 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 Foundation; either version 2
|
||||
** of the License, or (at your option) any later version.
|
||||
**
|
||||
** This program 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 this program; if not, write to the Free Software
|
||||
** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
** 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef HEADER_ABS_TO_REL_HPP
|
||||
#define HEADER_ABS_TO_REL_HPP
|
||||
|
||||
#include "control.hpp"
|
||||
|
||||
/** */
|
||||
class AbsToRel : public Control
|
||||
{
|
||||
private:
|
||||
public:
|
||||
AbsToRel();
|
||||
|
||||
void on_abs(AbsPortOut* port);
|
||||
|
||||
private:
|
||||
AbsToRel (const AbsToRel&);
|
||||
AbsToRel& operator= (const AbsToRel&);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
/* EOF */
|
40
control.cpp
40
control.cpp
|
@ -99,4 +99,44 @@ Control::get_abs_port_out(int idx)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
RelPortOut::connect(RelPortIn* in)
|
||||
{
|
||||
if (in)
|
||||
{
|
||||
in->out_port = this;
|
||||
sig_change.connect(in->on_change);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
RelPortOut::connect(boost::function<void(RelPortOut*)> func)
|
||||
{
|
||||
sig_change.connect(func);
|
||||
}
|
||||
|
||||
RelPortIn*
|
||||
Control::get_rel_port_in(int idx)
|
||||
{
|
||||
if (idx >= 0 && idx < (int)rel_port_in.size())
|
||||
return rel_port_in[idx];
|
||||
else
|
||||
{
|
||||
LOG("Couldn't find rel-in port " << idx);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
RelPortOut*
|
||||
Control::get_rel_port_out(int idx)
|
||||
{
|
||||
if (idx >= 0 && idx < (int)rel_port_out.size())
|
||||
return rel_port_out[idx];
|
||||
else
|
||||
{
|
||||
LOG("Couldn't find rel-out port " << idx);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
|
|
58
control.hpp
58
control.hpp
|
@ -102,13 +102,52 @@ public:
|
|||
boost::function<void(AbsPortOut*)> on_change;
|
||||
AbsPortOut* out_port;
|
||||
|
||||
AbsPortIn(const std::string& label, int min_value, int max_value, const boost::function<void(AbsPortOut*)>& on_change)
|
||||
AbsPortIn(const std::string& label, int min_value, int max_value,
|
||||
const boost::function<void(AbsPortOut*)>& on_change)
|
||||
: label(label),
|
||||
min_value(min_value),
|
||||
max_value(max_value),
|
||||
on_change(on_change), out_port(0) {}
|
||||
};
|
||||
|
||||
class RelPortIn;
|
||||
|
||||
class RelPortOut
|
||||
{
|
||||
public:
|
||||
std::string label;
|
||||
|
||||
boost::signal<void(RelPortOut*)> sig_change;
|
||||
|
||||
// true if pressed, false otherwise
|
||||
int state;
|
||||
|
||||
RelPortOut(const std::string& label)
|
||||
: label(label)
|
||||
{}
|
||||
|
||||
|
||||
std::string get_label() { return label; }
|
||||
int get_state() { return state; }
|
||||
void set_state(int s) { if (state != s) { state = s; sig_change(this); } }
|
||||
|
||||
void connect(RelPortIn* in);
|
||||
void connect(boost::function<void(RelPortOut*)> func);
|
||||
};
|
||||
|
||||
class RelPortIn
|
||||
{
|
||||
public:
|
||||
std::string label;
|
||||
|
||||
boost::function<void(RelPortOut*)> on_change;
|
||||
RelPortOut* out_port;
|
||||
|
||||
RelPortIn(const std::string& label, const boost::function<void(RelPortOut*)>& on_change)
|
||||
: label(label),
|
||||
on_change(on_change), out_port(0) {}
|
||||
};
|
||||
|
||||
class Control
|
||||
{
|
||||
protected:
|
||||
|
@ -118,6 +157,9 @@ protected:
|
|||
std::vector<AbsPortIn*> abs_port_in;
|
||||
std::vector<AbsPortOut*> abs_port_out;
|
||||
|
||||
std::vector<RelPortIn*> rel_port_in;
|
||||
std::vector<RelPortOut*> rel_port_out;
|
||||
|
||||
public:
|
||||
Control() {
|
||||
}
|
||||
|
@ -126,15 +168,18 @@ public:
|
|||
{
|
||||
for(std::vector<BtnPortIn*>::iterator i = btn_port_in.begin(); i != btn_port_in.end(); ++i)
|
||||
delete *i;
|
||||
|
||||
for(std::vector<BtnPortOut*>::iterator i = btn_port_out.begin(); i != btn_port_out.end(); ++i)
|
||||
delete *i;
|
||||
|
||||
for(std::vector<AbsPortIn*>::iterator i = abs_port_in.begin(); i != abs_port_in.end(); ++i)
|
||||
delete *i;
|
||||
|
||||
for(std::vector<AbsPortOut*>::iterator i = abs_port_out.begin(); i != abs_port_out.end(); ++i)
|
||||
delete *i;
|
||||
|
||||
for(std::vector<RelPortIn*>::iterator i = rel_port_in.begin(); i != rel_port_in.end(); ++i)
|
||||
delete *i;
|
||||
for(std::vector<RelPortOut*>::iterator i = rel_port_out.begin(); i != rel_port_out.end(); ++i)
|
||||
delete *i;
|
||||
}
|
||||
|
||||
int get_btn_port_in_count() { return btn_port_in.size(); }
|
||||
|
@ -149,6 +194,13 @@ public:
|
|||
|
||||
AbsPortIn* get_abs_port_in(int idx);
|
||||
AbsPortOut* get_abs_port_out(int idx);
|
||||
|
||||
|
||||
int get_rel_port_in_count() { return rel_port_in.size(); }
|
||||
int get_rel_port_out_count() { return rel_port_out.size(); }
|
||||
|
||||
RelPortIn* get_rel_port_in(int idx);
|
||||
RelPortOut* get_rel_port_out(int idx);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -45,6 +45,8 @@ void abs_change(AbsPortOut* port)
|
|||
int main()
|
||||
{
|
||||
UInputDriver uinput1;
|
||||
uinput1.add_rel(REL_X);
|
||||
uinput1.add_rel(REL_Y);
|
||||
uinput1.add_abs(ABS_X, -32768, 32767);
|
||||
uinput1.add_abs(ABS_Y, -32768, 32767);
|
||||
uinput1.add_btn(BTN_A);
|
||||
|
@ -60,7 +62,6 @@ int main()
|
|||
uinput2.add_btn(BTN_C);
|
||||
uinput2.finish();
|
||||
|
||||
|
||||
// Init USB
|
||||
usb_init();
|
||||
usb_find_busses();
|
||||
|
@ -94,7 +95,6 @@ int main()
|
|||
->connect(uinput1.get_btn_port_in(2));
|
||||
|
||||
// ----------------------------
|
||||
// ----------------------------
|
||||
|
||||
xbox360.get_abs_port_out(Xbox360Driver::XBOX360_AXIS_X2)
|
||||
->connect(uinput2.get_abs_port_in(0));
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
|
||||
UInputDriver::UInputDriver()
|
||||
: abs_bit(false),
|
||||
rel_bit(false),
|
||||
key_bit(false),
|
||||
fd(-1)
|
||||
{
|
||||
|
@ -79,7 +80,7 @@ UInputDriver::~UInputDriver()
|
|||
ioctl(fd, UI_DEV_DESTROY);
|
||||
close(fd);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
UInputDriver::add_abs(uint16_t code, int min, int max)
|
||||
{
|
||||
|
@ -99,17 +100,47 @@ UInputDriver::add_abs(uint16_t code, int min, int max)
|
|||
}
|
||||
|
||||
void
|
||||
UInputDriver::on_btn(BtnPortOut* port, uint16_t code)
|
||||
UInputDriver::add_rel(uint16_t code)
|
||||
{
|
||||
if (!rel_bit)
|
||||
{
|
||||
ioctl(fd, UI_SET_EVBIT, EV_REL);
|
||||
rel_bit = true;
|
||||
}
|
||||
|
||||
ioctl(fd, UI_SET_RELBIT, code);
|
||||
|
||||
rel_port_in.push_back(new RelPortIn("UInput",
|
||||
boost::bind(&UInputDriver::on_rel, this, _1, code)));
|
||||
}
|
||||
|
||||
void
|
||||
UInputDriver::add_btn(uint16_t code)
|
||||
{
|
||||
if (!key_bit)
|
||||
{
|
||||
ioctl(fd, UI_SET_EVBIT, EV_KEY);
|
||||
key_bit = true;
|
||||
}
|
||||
|
||||
ioctl(fd, UI_SET_KEYBIT, code);
|
||||
|
||||
btn_port_in.push_back(new BtnPortIn("UInput",
|
||||
boost::bind(&UInputDriver::on_btn, this, _1, code)));
|
||||
}
|
||||
|
||||
void
|
||||
UInputDriver::on_rel(RelPortOut* port, uint16_t code)
|
||||
{
|
||||
struct input_event ev;
|
||||
memset(&ev, 0, sizeof(ev));
|
||||
|
||||
gettimeofday(&ev.time, NULL);
|
||||
ev.type = EV_KEY;
|
||||
ev.type = EV_REL;
|
||||
ev.code = code;
|
||||
ev.value = port->get_state();
|
||||
|
||||
write(fd, &ev, sizeof(ev));
|
||||
write(fd, &ev, sizeof(ev));
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -127,20 +158,19 @@ UInputDriver::on_abs(AbsPortOut* port, uint16_t code)
|
|||
}
|
||||
|
||||
void
|
||||
UInputDriver::add_btn(uint16_t code)
|
||||
UInputDriver::on_btn(BtnPortOut* port, uint16_t code)
|
||||
{
|
||||
if (!key_bit)
|
||||
{
|
||||
ioctl(fd, UI_SET_EVBIT, EV_KEY);
|
||||
key_bit = true;
|
||||
}
|
||||
struct input_event ev;
|
||||
memset(&ev, 0, sizeof(ev));
|
||||
|
||||
ioctl(fd, UI_SET_KEYBIT, code);
|
||||
gettimeofday(&ev.time, NULL);
|
||||
ev.type = EV_KEY;
|
||||
ev.code = code;
|
||||
ev.value = port->get_state();
|
||||
|
||||
btn_port_in.push_back(new BtnPortIn("UInput",
|
||||
boost::bind(&UInputDriver::on_btn, this, _1, code)));
|
||||
write(fd, &ev, sizeof(ev));
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
UInputDriver::finish()
|
||||
{
|
||||
|
|
|
@ -35,6 +35,7 @@ class UInputDriver : public Control
|
|||
private:
|
||||
uinput_user_dev user_dev;
|
||||
bool abs_bit;
|
||||
bool rel_bit;
|
||||
bool key_bit;
|
||||
int fd;
|
||||
|
||||
|
@ -44,9 +45,11 @@ public:
|
|||
|
||||
void add_abs(uint16_t code, int min, int max);
|
||||
void add_btn(uint16_t code);
|
||||
void add_rel(uint16_t code);
|
||||
void finish();
|
||||
|
||||
void on_abs(AbsPortOut* port, uint16_t code);
|
||||
void on_rel(RelPortOut* port, uint16_t code);
|
||||
void on_btn(BtnPortOut* port, uint16_t code);
|
||||
|
||||
private:
|
||||
|
|
Loading…
Add table
Reference in a new issue