- implemented mouse emulation

This commit is contained in:
Ingo Ruhnke 2008-04-25 20:22:08 +02:00
parent 2719b3105e
commit 5008924201
7 changed files with 158 additions and 125 deletions

View file

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

View file

@ -36,7 +36,7 @@ public:
AbsToRel();
void on_abs(AbsPortOut* port);
void update(float delta);
private:
AbsToRel (const AbsToRel&);
AbsToRel& operator= (const AbsToRel&);

View file

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

View file

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

View file

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

View file

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

View file

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