Added some upport for rel events

This commit is contained in:
Ingo Ruhnke 2008-04-25 08:00:10 +02:00
parent 74f8aa534f
commit 2719b3105e
8 changed files with 234 additions and 19 deletions

View file

@ -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
View 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
View 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 */

View file

@ -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 */

View file

@ -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

View file

@ -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));

View file

@ -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()
{

View file

@ -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: