- implemented mouse emulation
This commit is contained in:
parent
2719b3105e
commit
5008924201
7 changed files with 158 additions and 125 deletions
|
@ -36,7 +36,15 @@ AbsToRel::AbsToRel()
|
|||
void
|
||||
AbsToRel::on_abs(AbsPortOut* port)
|
||||
{
|
||||
rel_port_out[0]->set_state(port->get_state());
|
||||
// Nothing do to, since everything is handled in update
|
||||
//rel_port_out[0]->set_state(port->get_state());
|
||||
}
|
||||
|
||||
void
|
||||
AbsToRel::update(float delta)
|
||||
{
|
||||
int s = int(abs_port_in[0]->out_port->get_state() * delta * 0.2f);
|
||||
rel_port_out[0]->set_state(s);
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
|
|
|
@ -36,7 +36,7 @@ public:
|
|||
AbsToRel();
|
||||
|
||||
void on_abs(AbsPortOut* port);
|
||||
|
||||
void update(float delta);
|
||||
private:
|
||||
AbsToRel (const AbsToRel&);
|
||||
AbsToRel& operator= (const AbsToRel&);
|
||||
|
|
|
@ -129,7 +129,7 @@ public:
|
|||
|
||||
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 set_state(int s) { state = s; sig_change(this); }
|
||||
|
||||
void connect(RelPortIn* in);
|
||||
void connect(boost::function<void(RelPortOut*)> func);
|
||||
|
@ -201,6 +201,9 @@ public:
|
|||
|
||||
RelPortIn* get_rel_port_in(int idx);
|
||||
RelPortOut* get_rel_port_out(int idx);
|
||||
|
||||
|
||||
virtual void update(float delta) {}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
119
inputdrv.cpp
119
inputdrv.cpp
|
@ -28,6 +28,7 @@
|
|||
#include <boost/bind.hpp>
|
||||
#include "xbox360_driver.hpp"
|
||||
#include "uinput_driver.hpp"
|
||||
#include "abs_to_rel.hpp"
|
||||
#include "toggle_button.hpp"
|
||||
#include "control.hpp"
|
||||
#include "inputdrv.hpp"
|
||||
|
@ -44,81 +45,85 @@ 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);
|
||||
uinput1.add_btn(BTN_B);
|
||||
uinput1.add_btn(BTN_C);
|
||||
uinput1.finish();
|
||||
|
||||
UInputDriver uinput2;
|
||||
uinput2.add_abs(ABS_X, -32768, 32767);
|
||||
uinput2.add_abs(ABS_Y, -32768, 32767);
|
||||
uinput2.add_btn(BTN_A);
|
||||
uinput2.add_btn(BTN_B);
|
||||
uinput2.add_btn(BTN_C);
|
||||
uinput2.finish();
|
||||
UInputDriver* uinput = new UInputDriver();
|
||||
uinput->add_rel(REL_X);
|
||||
uinput->add_rel(REL_Y);
|
||||
uinput->add_rel(REL_HWHEEL);
|
||||
uinput->add_rel(REL_WHEEL);
|
||||
uinput->add_btn(BTN_LEFT);
|
||||
uinput->add_btn(BTN_RIGHT);
|
||||
uinput->add_btn(BTN_MIDDLE);
|
||||
uinput->finish();
|
||||
|
||||
// Init USB
|
||||
usb_init();
|
||||
usb_find_busses();
|
||||
usb_find_devices();
|
||||
|
||||
Xbox360Driver xbox360(0);
|
||||
ToggleButton toggle;
|
||||
std::vector<Control*> controls;
|
||||
|
||||
BtnPortOut* btn_a = xbox360.get_btn_port_out(Xbox360Driver::XBOX360_BTN_A);
|
||||
BtnPortOut* btn_b = xbox360.get_btn_port_out(Xbox360Driver::XBOX360_BTN_B);
|
||||
BtnPortIn* toggle_in = toggle.get_btn_port_in(0);
|
||||
BtnPortOut* toggle_out = toggle.get_btn_port_out(0);
|
||||
Xbox360Driver* xbox360 = new Xbox360Driver(0);
|
||||
ToggleButton* toggle = new ToggleButton();
|
||||
AbsToRel* abs_to_rel_x = new AbsToRel();
|
||||
AbsToRel* abs_to_rel_y = new AbsToRel();
|
||||
AbsToRel* abs_to_rel_x2 = new AbsToRel();
|
||||
AbsToRel* abs_to_rel_y2 = new AbsToRel();
|
||||
|
||||
btn_a->connect(btn_change);
|
||||
btn_b->connect(toggle_in);
|
||||
|
||||
toggle_out->connect(xbox360.get_btn_port_in(0));
|
||||
controls.push_back(xbox360);
|
||||
controls.push_back(toggle);
|
||||
controls.push_back(abs_to_rel_x);
|
||||
controls.push_back(abs_to_rel_y);
|
||||
controls.push_back(abs_to_rel_x2);
|
||||
controls.push_back(abs_to_rel_y2);
|
||||
|
||||
// ----------------------------
|
||||
|
||||
xbox360.get_abs_port_out(Xbox360Driver::XBOX360_AXIS_X1)
|
||||
->connect(uinput1.get_abs_port_in(0));
|
||||
xbox360.get_abs_port_out(Xbox360Driver::XBOX360_AXIS_Y1)
|
||||
->connect(uinput1.get_abs_port_in(1));
|
||||
xbox360->get_abs_port_out(Xbox360Driver::XBOX360_AXIS_X1)
|
||||
->connect(abs_to_rel_x->get_abs_port_in(0));
|
||||
xbox360->get_abs_port_out(Xbox360Driver::XBOX360_AXIS_Y1)
|
||||
->connect(abs_to_rel_y->get_abs_port_in(0));
|
||||
|
||||
xbox360.get_btn_port_out(Xbox360Driver::XBOX360_BTN_A)
|
||||
->connect(uinput1.get_btn_port_in(0));
|
||||
xbox360.get_btn_port_out(Xbox360Driver::XBOX360_BTN_B)
|
||||
->connect(uinput1.get_btn_port_in(1));
|
||||
xbox360.get_btn_port_out(Xbox360Driver::XBOX360_BTN_X)
|
||||
->connect(uinput1.get_btn_port_in(2));
|
||||
xbox360->get_abs_port_out(Xbox360Driver::XBOX360_AXIS_X2)
|
||||
->connect(abs_to_rel_x2->get_abs_port_in(0));
|
||||
xbox360->get_abs_port_out(Xbox360Driver::XBOX360_AXIS_Y2)
|
||||
->connect(abs_to_rel_y2->get_abs_port_in(0));
|
||||
|
||||
abs_to_rel_x->get_rel_port_out(0)
|
||||
->connect(uinput->get_rel_port_in(0));
|
||||
abs_to_rel_y->get_rel_port_out(0)
|
||||
->connect(uinput->get_rel_port_in(1));
|
||||
abs_to_rel_x2->get_rel_port_out(0)
|
||||
->connect(uinput->get_rel_port_in(2));
|
||||
abs_to_rel_y2->get_rel_port_out(0)
|
||||
->connect(uinput->get_rel_port_in(3));
|
||||
|
||||
xbox360->get_btn_port_out(Xbox360Driver::XBOX360_BTN_A)
|
||||
->connect(uinput->get_btn_port_in(0));
|
||||
xbox360->get_btn_port_out(Xbox360Driver::XBOX360_BTN_B)
|
||||
->connect(uinput->get_btn_port_in(1));
|
||||
xbox360->get_btn_port_out(Xbox360Driver::XBOX360_BTN_X)
|
||||
->connect(uinput->get_btn_port_in(2));
|
||||
|
||||
// ----------------------------
|
||||
|
||||
xbox360.get_abs_port_out(Xbox360Driver::XBOX360_AXIS_X2)
|
||||
->connect(uinput2.get_abs_port_in(0));
|
||||
xbox360.get_abs_port_out(Xbox360Driver::XBOX360_AXIS_Y2)
|
||||
->connect(uinput2.get_abs_port_in(1));
|
||||
xbox360->get_abs_port_out(Xbox360Driver::XBOX360_AXIS_LT)
|
||||
->connect(xbox360->get_abs_port_in(Xbox360Driver::ABS_PORT_IN_RUMBLE_L));
|
||||
|
||||
xbox360.get_btn_port_out(Xbox360Driver::XBOX360_DPAD_DOWN)
|
||||
->connect(uinput2.get_btn_port_in(0));
|
||||
xbox360.get_btn_port_out(Xbox360Driver::XBOX360_DPAD_LEFT)
|
||||
->connect(uinput2.get_btn_port_in(1));
|
||||
xbox360.get_btn_port_out(Xbox360Driver::XBOX360_DPAD_RIGHT)
|
||||
->connect(uinput2.get_btn_port_in(2));
|
||||
|
||||
// ----------------------------
|
||||
xbox360->get_abs_port_out(Xbox360Driver::XBOX360_AXIS_RT)
|
||||
->connect(xbox360->get_abs_port_in(Xbox360Driver::ABS_PORT_IN_RUMBLE_R));
|
||||
|
||||
xbox360.get_abs_port_out(Xbox360Driver::XBOX360_AXIS_LT)
|
||||
->connect(xbox360.get_abs_port_in(Xbox360Driver::ABS_PORT_IN_RUMBLE_L));
|
||||
xbox360->get_btn_port_out(Xbox360Driver::XBOX360_BTN_Y)->connect(btn_change);
|
||||
|
||||
xbox360.get_abs_port_out(Xbox360Driver::XBOX360_AXIS_RT)
|
||||
->connect(xbox360.get_abs_port_in(Xbox360Driver::ABS_PORT_IN_RUMBLE_R));
|
||||
|
||||
xbox360.get_btn_port_out(Xbox360Driver::XBOX360_BTN_Y)->connect(btn_change);
|
||||
|
||||
xbox360.run();
|
||||
bool quit = false;
|
||||
while(!quit)
|
||||
{
|
||||
for(std::vector<Control*>::iterator i = controls.begin(); i != controls.end(); ++i)
|
||||
{
|
||||
(*i)->update(0.001f);
|
||||
}
|
||||
//std::cout << "." << std::flush;
|
||||
//usleep(1000); // 0.001sec or 1msec
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -132,15 +132,27 @@ UInputDriver::add_btn(uint16_t code)
|
|||
void
|
||||
UInputDriver::on_rel(RelPortOut* port, uint16_t code)
|
||||
{
|
||||
struct input_event ev;
|
||||
memset(&ev, 0, sizeof(ev));
|
||||
if (port->get_state() != 0)
|
||||
{
|
||||
struct input_event ev;
|
||||
memset(&ev, 0, sizeof(ev));
|
||||
|
||||
gettimeofday(&ev.time, NULL);
|
||||
ev.type = EV_REL;
|
||||
ev.code = code;
|
||||
ev.value = port->get_state();
|
||||
gettimeofday(&ev.time, NULL);
|
||||
ev.type = EV_REL;
|
||||
ev.code = code;
|
||||
ev.value = port->get_state();
|
||||
|
||||
write(fd, &ev, sizeof(ev));
|
||||
write(fd, &ev, sizeof(ev));
|
||||
|
||||
// Mouse Dev need these to send out events
|
||||
memset(&ev, 0, sizeof(ev));
|
||||
|
||||
gettimeofday(&ev.time, NULL);
|
||||
ev.type = EV_SYN;
|
||||
ev.code = SYN_REPORT;
|
||||
|
||||
write(fd, &ev, sizeof(ev));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -154,7 +166,7 @@ UInputDriver::on_abs(AbsPortOut* port, uint16_t code)
|
|||
ev.code = code;
|
||||
ev.value = port->get_state();
|
||||
|
||||
write(fd, &ev, sizeof(ev));
|
||||
write(fd, &ev, sizeof(ev));
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -168,7 +180,16 @@ UInputDriver::on_btn(BtnPortOut* port, uint16_t code)
|
|||
ev.code = code;
|
||||
ev.value = port->get_state();
|
||||
|
||||
write(fd, &ev, sizeof(ev));
|
||||
write(fd, &ev, sizeof(ev));
|
||||
|
||||
// Mouse Dev need these to send out events
|
||||
memset(&ev, 0, sizeof(ev));
|
||||
|
||||
gettimeofday(&ev.time, NULL);
|
||||
ev.type = EV_SYN;
|
||||
ev.code = SYN_REPORT;
|
||||
|
||||
write(fd, &ev, sizeof(ev));
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -24,6 +24,8 @@
|
|||
*/
|
||||
|
||||
#include <usb.h>
|
||||
#include <errno.h>
|
||||
#include <sstream>
|
||||
#include <iostream>
|
||||
#include <boost/format.hpp>
|
||||
#include <boost/bind.hpp>
|
||||
|
@ -166,66 +168,60 @@ Xbox360Driver::close_dev()
|
|||
}
|
||||
|
||||
void
|
||||
Xbox360Driver::run()
|
||||
{ // Run this in a seperate Thread
|
||||
bool quit = false;
|
||||
uint8_t old_data[20];
|
||||
memset(old_data, 0, 20);
|
||||
while(!quit)
|
||||
{
|
||||
uint8_t data[20];
|
||||
Xbox360Driver::update(float delta)
|
||||
{ // Run this in a seperate Thread
|
||||
|
||||
uint8_t data[20];
|
||||
|
||||
int ret = usb_interrupt_read(handle, 1 /*EndPoint*/, (char*)data, 20, 0 /*Timeout*/);
|
||||
int ret = usb_interrupt_read(handle, 1 /*EndPoint*/, (char*)data, 20, 5 /*Timeout*/);
|
||||
|
||||
if (ret < 0)
|
||||
{ // Error
|
||||
std::cout << "USBError: " << ret << "\n" << usb_strerror() << std::endl;
|
||||
std::cout << "Shutting down" << std::endl;
|
||||
quit = true;
|
||||
}
|
||||
else if (ret == 0) // ignore
|
||||
{
|
||||
// happen with the Xbox360 every now and then, just
|
||||
// ignore, seems harmless
|
||||
}
|
||||
else if (ret == 3) // ignore
|
||||
{
|
||||
// This data gets send when the controller is accessed the
|
||||
// first time after being connected to the USB bus, no idea
|
||||
// what it means, it seems to be identical for different
|
||||
// controllers, we just ignore it
|
||||
//
|
||||
// len: 3 Data: 0x01 0x03 0x0e
|
||||
// len: 3 Data: 0x02 0x03 0x00
|
||||
// len: 3 Data: 0x03 0x03 0x03
|
||||
// len: 3 Data: 0x08 0x03 0x00
|
||||
// len: 3 Data: 0x01 0x03 0x00
|
||||
}
|
||||
else if (ret == 20 && data[0] == 0x00 && data[1] == 0x14)
|
||||
{
|
||||
if (memcmp(data, old_data, 20) == 0)
|
||||
{
|
||||
// Ignore the data, since nothing has changed
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(old_data, data, 20);
|
||||
Xbox360Msg& msg = (Xbox360Msg&)data;
|
||||
update(msg);
|
||||
}
|
||||
if (ret < 0)
|
||||
{
|
||||
if (ret == -ETIMEDOUT)
|
||||
{ // ok
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "Unknown data: bytes: " << ret << " Data: ";
|
||||
for(int j = 0; j < ret; ++j)
|
||||
std::cout << boost::format("0x%02x ") % int(data[j]);
|
||||
std::cout << std::endl;
|
||||
}
|
||||
{ // Error
|
||||
std::ostringstream str;
|
||||
str << "USBError: " << ret << "\n" << usb_strerror() << std::endl;
|
||||
str << "Shutting down" << std::endl;
|
||||
throw std::runtime_error(str.str());
|
||||
}
|
||||
}
|
||||
else if (ret == 0) // ignore
|
||||
{
|
||||
// happen with the Xbox360 every now and then, just
|
||||
// ignore, seems harmless
|
||||
}
|
||||
else if (ret == 3) // ignore
|
||||
{
|
||||
// This data gets send when the controller is accessed the
|
||||
// first time after being connected to the USB bus, no idea
|
||||
// what it means, it seems to be identical for different
|
||||
// controllers, we just ignore it
|
||||
//
|
||||
// len: 3 Data: 0x01 0x03 0x0e
|
||||
// len: 3 Data: 0x02 0x03 0x00
|
||||
// len: 3 Data: 0x03 0x03 0x03
|
||||
// len: 3 Data: 0x08 0x03 0x00
|
||||
// len: 3 Data: 0x01 0x03 0x00
|
||||
}
|
||||
else if (ret == 20 && data[0] == 0x00 && data[1] == 0x14)
|
||||
{
|
||||
Xbox360Msg& msg = (Xbox360Msg&)data;
|
||||
process_msg(msg);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "Unknown data: bytes: " << ret << " Data: ";
|
||||
for(int j = 0; j < ret; ++j)
|
||||
std::cout << boost::format("0x%02x ") % int(data[j]);
|
||||
std::cout << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Xbox360Driver::update(const Xbox360Msg& msg)
|
||||
Xbox360Driver::process_msg(const Xbox360Msg& msg)
|
||||
{
|
||||
btn_port_out[XBOX360_DPAD_UP] ->set_state(msg.dpad_up);
|
||||
btn_port_out[XBOX360_DPAD_DOWN] ->set_state(msg.dpad_down);
|
||||
|
@ -248,10 +244,10 @@ Xbox360Driver::update(const Xbox360Msg& msg)
|
|||
btn_port_out[XBOX360_BTN_GUIDE]->set_state(msg.guide);
|
||||
|
||||
abs_port_out[XBOX360_AXIS_X1]->set_state(msg.x1);
|
||||
abs_port_out[XBOX360_AXIS_Y1]->set_state(msg.y1);
|
||||
abs_port_out[XBOX360_AXIS_Y1]->set_state(-msg.y1);
|
||||
|
||||
abs_port_out[XBOX360_AXIS_X2]->set_state(msg.x2);
|
||||
abs_port_out[XBOX360_AXIS_Y2]->set_state(msg.y2);
|
||||
abs_port_out[XBOX360_AXIS_Y2]->set_state(-msg.y2);
|
||||
|
||||
abs_port_out[XBOX360_AXIS_LT]->set_state(msg.lt);
|
||||
abs_port_out[XBOX360_AXIS_RT]->set_state(msg.rt);
|
||||
|
|
|
@ -100,13 +100,13 @@ public:
|
|||
void on_rumble_left_abs(AbsPortOut* abs);
|
||||
void on_rumble_right_abs(AbsPortOut* abs);
|
||||
|
||||
void run();
|
||||
void update(float delta);
|
||||
|
||||
private:
|
||||
void init();
|
||||
void open_dev();
|
||||
void close_dev();
|
||||
void update(const Xbox360Msg& msg);
|
||||
void process_msg(const Xbox360Msg& msg);
|
||||
|
||||
Xbox360Driver (const Xbox360Driver&);
|
||||
Xbox360Driver& operator= (const Xbox360Driver&);
|
||||
|
|
Loading…
Add table
Reference in a new issue