X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Finput%2Flinux%2Fgamecontroller.cpp;h=06008bcf90b0adcd2abd89d6e05eac457b049992;hb=HEAD;hp=7fc59ed6669d0f99f11758f352ac1a478550b570;hpb=d17c22c1da1915afbcb9e39f4bd5e7e28259a110;p=libs%2Fgui.git diff --git a/source/input/linux/gamecontroller.cpp b/source/input/linux/gamecontroller.cpp index 7fc59ed..06008bc 100644 --- a/source/input/linux/gamecontroller.cpp +++ b/source/input/linux/gamecontroller.cpp @@ -1,22 +1,35 @@ +#include "gamecontroller.h" +#include "gamecontroller_platform.h" #include #include +#include #include +#include #include #include -#include "gamecontroller.h" -#include "gamecontroller_platform.h" using namespace std; namespace Msp { namespace Input { +vector GameController::Private::detected_controllers; + GameController::GameController(unsigned index): - priv(new Private) + Device(GAME_CONTROLLER) { - priv->dev = new JsDevice(format("/dev/input/js%d", index)); + if(!detect_done) + detect(); + if(index>=Private::detected_controllers.size()) + throw device_not_available(format("GameController(%d)", index)); + + JsDevice *device = new JsDevice(Private::detected_controllers[index]); + + priv = new Private; + priv->dev = device; + priv->dev->signal_data_available.connect(sigc::mem_fun(this, static_cast(&GameController::tick))); name = priv->dev->get_name(); - tick(); + tick(Time::zero); } GameController::~GameController() @@ -25,21 +38,52 @@ GameController::~GameController() delete priv; } +unsigned GameController::detect() +{ + Private::detected_controllers.clear(); + + FS::Path dev_input = "/dev/input"; + vector devices = FS::list_filtered(dev_input, "^js[0-9]+"); + sort(devices); + for(const string &f: devices) + // TODO check permissions + Private::detected_controllers.push_back((dev_input/f).str()); + + detect_done = true; + n_detected_controllers = Private::detected_controllers.size(); + + return Private::detected_controllers.size(); +} + +void GameController::use_event_dispatcher(IO::EventDispatcher *ed) +{ + if(event_disp) + event_disp->remove(*priv->dev); + event_disp = ed; + if(event_disp) + event_disp->add(*priv->dev); +} + void GameController::tick() { js_event events[16]; + bool first = true; while(1) { + if(!first && !IO::poll(*priv->dev, IO::P_INPUT, Time::zero)) + break; + + first = false; unsigned len = priv->dev->read(reinterpret_cast(events), sizeof(events)); unsigned count = len/sizeof(js_event); for(unsigned i=0; idev, IO::P_INPUT, timeout)) + tick(); +} + + JsDevice::JsDevice(const string &fn) { mode = IO::M_READ; - *handle = open(fn.c_str(), O_RDONLY|O_NONBLOCK); + *handle = open(fn.c_str(), O_RDONLY); if(!handle) throw system_error(format("open(%s)", fn)); + set_events(IO::P_INPUT); } JsDevice::~JsDevice() @@ -71,12 +123,12 @@ string JsDevice::get_name() const return buf; } -unsigned JsDevice::do_read(char *buf, unsigned size) +size_t JsDevice::do_read(char *buf, size_t size) { return IO::sys_read(handle, buf, size); } -unsigned JsDevice::do_write(const char *, unsigned) +size_t JsDevice::do_write(const char *, size_t) { throw IO::invalid_access(IO::M_WRITE); }