Some framework for integrating libusb into a glib main loop and async support for Controller, test app seems to be working, full xboxdrv will not
This commit is contained in:
parent
a5ccae7373
commit
3c85ad5765
15 changed files with 599 additions and 14 deletions
22
.gitignore
vendored
22
.gitignore
vendored
|
@ -1,18 +1,20 @@
|
|||
*~
|
||||
*.o
|
||||
.sconsign.dblite
|
||||
xboxdrv
|
||||
old
|
||||
*~
|
||||
.sconf_temp/
|
||||
config.log
|
||||
doc/xboxdrv-daemon.html/
|
||||
doc/xboxdrv.html/
|
||||
doc/xboxdrv.ent
|
||||
custom.py
|
||||
.sconsign.dblite
|
||||
cache/
|
||||
config.log
|
||||
custom.py
|
||||
doc/xboxdrv-daemon.html/
|
||||
doc/xboxdrv.ent
|
||||
doc/xboxdrv.html/
|
||||
libxboxdrv.a
|
||||
test/ini_parser_test
|
||||
old
|
||||
src/xboxdrv_controller_glue.hpp
|
||||
src/xboxdrv_daemon_glue.hpp
|
||||
src/xboxdrv_dbus_glue.hpp
|
||||
src/xboxdrv_vfs.hpp
|
||||
test/ini_parser_test
|
||||
test/usb_read_thread_test
|
||||
test/usb_system_test
|
||||
xboxdrv
|
||||
|
|
6
TODO
6
TODO
|
@ -55,11 +55,13 @@ $ sudo pbuilder --build --basetgz /var/cache/pbuilder/base-lucid.tgz ../xboxdrv-
|
|||
Stuff to do before 0.7.4 release:
|
||||
=================================
|
||||
|
||||
* deadzone:MIN:MAX:SMOOTH is broken
|
||||
* export build-in config files, both as text and as directory, so that users can browse them
|
||||
|
||||
* deadzone:MIN:MAX:SMOOTH is broken (fixed)
|
||||
|
||||
* deadzone filter documentation is wrong
|
||||
|
||||
* d-bus requires X11?!
|
||||
* d-bus requires X11?! -> try system bus when running as root
|
||||
|
||||
Autolaunch error: X11 initialization failed." failed to open connection to bus: /bin/dbus-launch terminated abnormally with the following error: Autolaunch error: X11 initialization failed.
|
||||
|
||||
|
|
36
src/controller.cpp
Normal file
36
src/controller.cpp
Normal file
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
** Xbox360 USB Gamepad Userspace Driver
|
||||
** Copyright (C) 2011 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "controller.hpp"
|
||||
|
||||
void
|
||||
Controller::set_msg_callback(const boost::function<void(const XboxGenericMsg&)>& callback)
|
||||
{
|
||||
m_callback = callback;
|
||||
}
|
||||
|
||||
void
|
||||
Controller::submit_msg(const XboxGenericMsg& msg)
|
||||
{
|
||||
if (m_callback)
|
||||
{
|
||||
m_callback(msg);
|
||||
}
|
||||
}
|
||||
|
||||
/* EOF */
|
|
@ -27,10 +27,16 @@ struct XboxGenericMsg;
|
|||
|
||||
class Controller
|
||||
{
|
||||
private:
|
||||
boost::function<void(const XboxGenericMsg& msg)> m_callback;
|
||||
|
||||
public:
|
||||
Controller() {}
|
||||
Controller() : m_callback() {}
|
||||
virtual ~Controller() {}
|
||||
|
||||
virtual void start() {}
|
||||
virtual void stop() {}
|
||||
|
||||
virtual void set_rumble(uint8_t left, uint8_t right) =0;
|
||||
virtual void set_led(uint8_t status) =0;
|
||||
|
||||
|
@ -47,6 +53,9 @@ public:
|
|||
virtual std::string get_usbid() const { return "-1:-1"; }
|
||||
virtual std::string get_name() const { return "<not implemented>"; }
|
||||
|
||||
void set_msg_callback(const boost::function<void(const XboxGenericMsg&)>& callback);
|
||||
void submit_msg(const XboxGenericMsg& msg);
|
||||
|
||||
private:
|
||||
Controller (const Controller&);
|
||||
Controller& operator= (const Controller&);
|
||||
|
|
|
@ -129,6 +129,30 @@ EvdevController::EvdevController(const std::string& filename,
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
EvdevController::start()
|
||||
{
|
||||
GIOChannel* channel = g_io_channel_unix_new(m_fd);
|
||||
|
||||
// set encoding to binary
|
||||
GError* error;
|
||||
if (g_io_channel_set_encoding(channel, NULL, &error) != G_IO_STATUS_NORMAL)
|
||||
{
|
||||
log_error(error->message);
|
||||
g_error_free(error);
|
||||
}
|
||||
|
||||
guint source_id;
|
||||
source_id = g_io_add_watch(channel, static_cast<GIOCondition>(G_IO_IN | G_IO_ERR),
|
||||
&EvdevController::on_read_data_wrap, this);
|
||||
}
|
||||
|
||||
void
|
||||
EvdevController::stop()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
EvdevController::set_rumble(uint8_t left, uint8_t right)
|
||||
{
|
||||
|
@ -247,4 +271,13 @@ EvdevController::read(XboxGenericMsg& msg, int timeout)
|
|||
return false;
|
||||
}
|
||||
|
||||
gboolean
|
||||
EvdevController::on_read_data(GIOChannel* source, GIOCondition condition)
|
||||
{
|
||||
//int fd = g_io_channel_unix_get_fd(source);
|
||||
|
||||
// process data
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
|
||||
#include <linux/input.h>
|
||||
#include <string>
|
||||
#include <glib.h>
|
||||
#include <queue>
|
||||
|
||||
#include "evdev_absmap.hpp"
|
||||
|
@ -54,6 +55,9 @@ public:
|
|||
bool grab,
|
||||
bool debug);
|
||||
|
||||
void start();
|
||||
void stop();
|
||||
|
||||
void set_rumble(uint8_t left, uint8_t right);
|
||||
void set_led(uint8_t status);
|
||||
|
||||
|
@ -64,6 +68,16 @@ private:
|
|||
bool apply(XboxGenericMsg& msg, const struct input_event& ev);
|
||||
void read_data_to_buffer();
|
||||
|
||||
gboolean on_read_data(GIOChannel* source,
|
||||
GIOCondition condition);
|
||||
|
||||
static gboolean on_read_data_wrap(GIOChannel* source,
|
||||
GIOCondition condition,
|
||||
gpointer userdata)
|
||||
{
|
||||
return static_cast<EvdevController*>(userdata)->on_read_data(source, condition);
|
||||
}
|
||||
|
||||
private:
|
||||
EvdevController(const EvdevController&);
|
||||
EvdevController& operator=(const EvdevController&);
|
||||
|
|
11
src/log.hpp
11
src/log.hpp
|
@ -94,6 +94,17 @@ public:
|
|||
} \
|
||||
} while(false)
|
||||
|
||||
/** Write an empty debug level message, thus class and function name
|
||||
are visible */
|
||||
#define log_trace() do { \
|
||||
if (g_logger.get_log_level() >= Logger::kDebug) \
|
||||
{ \
|
||||
std::ostringstream x6ac1c382; \
|
||||
x6ac1c382 << log_pretty_print(__PRETTY_FUNCTION__); \
|
||||
g_logger.append_unchecked(Logger::kDebug, x6ac1c382.str()); \
|
||||
} \
|
||||
} while(false)
|
||||
|
||||
extern Logger g_logger;
|
||||
|
||||
#endif
|
||||
|
|
|
@ -20,8 +20,10 @@
|
|||
|
||||
#include <boost/format.hpp>
|
||||
|
||||
#include "usb_helper.hpp"
|
||||
#include "log.hpp"
|
||||
#include "raise_exception.hpp"
|
||||
#include "usb_helper.hpp"
|
||||
#include "xboxmsg.hpp"
|
||||
|
||||
USBController::USBController(libusb_device* dev) :
|
||||
m_dev(dev),
|
||||
|
@ -98,6 +100,57 @@ USBController::get_name() const
|
|||
return m_name;
|
||||
}
|
||||
|
||||
void
|
||||
USBController::usb_submit_read(int endpoint, int len)
|
||||
{
|
||||
log_debug("ep: " << endpoint << " len: " << len);
|
||||
|
||||
libusb_transfer* transfer = libusb_alloc_transfer(0);
|
||||
|
||||
uint8_t* data = static_cast<uint8_t*>(malloc(sizeof(uint8_t) * len));
|
||||
//FIXME: transfer->flags |= LIBUSB_TRANSFER_FREE_BUFFER;
|
||||
libusb_fill_interrupt_transfer(transfer, m_handle,
|
||||
endpoint | LIBUSB_ENDPOINT_IN,
|
||||
data, len,
|
||||
&USBController::on_read_data_wrap, this,
|
||||
0); // timeout
|
||||
int ret;
|
||||
ret = libusb_submit_transfer(transfer);
|
||||
log_debug("libusb_submit_transfer: " << usb_strerror(ret));
|
||||
}
|
||||
|
||||
void
|
||||
USBController::usb_cancel_read()
|
||||
{
|
||||
assert(!"implement me");
|
||||
}
|
||||
|
||||
void
|
||||
USBController::on_read_data(libusb_transfer *transfer)
|
||||
{
|
||||
log_trace();
|
||||
|
||||
assert(transfer);
|
||||
|
||||
// process data
|
||||
XboxGenericMsg msg;
|
||||
if (parse(transfer->buffer, transfer->actual_length, &msg))
|
||||
{
|
||||
submit_msg(msg);
|
||||
}
|
||||
|
||||
if (false) // cleanup
|
||||
{
|
||||
libusb_free_transfer(transfer);
|
||||
}
|
||||
else // resubmit
|
||||
{
|
||||
int ret;
|
||||
ret = libusb_submit_transfer(transfer);
|
||||
assert(ret == LIBUSB_SUCCESS); // FIXME
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
USBController::usb_claim_interface(int ifnum, bool try_detach)
|
||||
{
|
||||
|
|
|
@ -54,6 +54,15 @@ public:
|
|||
void usb_write(int endpoint, uint8_t* data, int len);
|
||||
int usb_find_ep(int direction, uint8_t if_class, uint8_t if_subclass, uint8_t if_protocol);
|
||||
|
||||
void usb_submit_read(int endpoint, int len);
|
||||
void usb_cancel_read();
|
||||
|
||||
void on_read_data(libusb_transfer *transfer);
|
||||
static void on_read_data_wrap(libusb_transfer *transfer)
|
||||
{
|
||||
static_cast<USBController*>(transfer->user_data)->on_read_data(transfer);
|
||||
}
|
||||
|
||||
private:
|
||||
USBController(const USBController&);
|
||||
USBController& operator=(const USBController&);
|
||||
|
|
155
src/usb_system.cpp
Normal file
155
src/usb_system.cpp
Normal file
|
@ -0,0 +1,155 @@
|
|||
/*
|
||||
** Xbox360 USB Gamepad Userspace Driver
|
||||
** Copyright (C) 2011 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "usb_system.hpp"
|
||||
|
||||
#include <assert.h>
|
||||
#include <poll.h>
|
||||
#include <libusb.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "log.hpp"
|
||||
|
||||
// GUSBSource
|
||||
|
||||
// documentation at: http://library.gnome.org/devel/glib/2.28/
|
||||
USBSystem::USBSystem() :
|
||||
m_source_funcs(),
|
||||
m_source(),
|
||||
m_source_id()
|
||||
{
|
||||
// create the source functions
|
||||
m_source_funcs.prepare = &USBSystem::on_source_prepare;
|
||||
m_source_funcs.check = &USBSystem::on_source_check;
|
||||
m_source_funcs.dispatch = &USBSystem::on_source_dispatch;
|
||||
m_source_funcs.finalize = NULL;
|
||||
|
||||
m_source_funcs.closure_callback = NULL;
|
||||
m_source_funcs.closure_marshal = NULL;
|
||||
|
||||
// create the source itself
|
||||
m_source = g_source_new(&m_source_funcs, sizeof(GSource));
|
||||
g_source_set_callback(m_source,
|
||||
&USBSystem::on_source_wrap, this,
|
||||
NULL);
|
||||
|
||||
// add pollfds to source
|
||||
const libusb_pollfd** fds = libusb_get_pollfds(NULL);
|
||||
for(const libusb_pollfd** i = fds; *i != NULL; ++i)
|
||||
{
|
||||
log_debug("adding pollfd: " << (*i)->fd);
|
||||
GPollFD* gfd = new GPollFD;
|
||||
|
||||
gfd->fd = (*i)->fd;
|
||||
gfd->events = (*i)->events;
|
||||
gfd->revents = 0;
|
||||
|
||||
g_source_add_poll(m_source, gfd);
|
||||
}
|
||||
free(fds);
|
||||
|
||||
// register pollfd callbacks
|
||||
libusb_set_pollfd_notifiers(NULL,
|
||||
&USBSystem::on_usb_pollfd_added_wrap,
|
||||
&USBSystem::on_usb_pollfd_removed_wrap,
|
||||
this);
|
||||
}
|
||||
|
||||
USBSystem::~USBSystem()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
USBSystem::attach(GMainContext* context)
|
||||
{
|
||||
// attach source
|
||||
m_source_id = g_source_attach(m_source, context);
|
||||
}
|
||||
|
||||
void
|
||||
USBSystem::on_usb_pollfd_added(int fd, short events)
|
||||
{
|
||||
assert(POLLIN == G_IO_IN);
|
||||
assert(POLLOUT == G_IO_OUT);
|
||||
|
||||
log_trace();
|
||||
GPollFD* gfd = new GPollFD;
|
||||
|
||||
gfd->fd = fd;
|
||||
gfd->events = events;
|
||||
gfd->revents = 0;
|
||||
|
||||
g_source_add_poll(m_source, gfd);
|
||||
|
||||
// FIXME: put gfd somewhere, like a map or list
|
||||
}
|
||||
|
||||
void
|
||||
USBSystem::on_usb_pollfd_removed(int fd)
|
||||
{
|
||||
log_trace();
|
||||
// FIXME: how to get the GPollFD
|
||||
//g_source_remove_poll(m_source, &gfd);
|
||||
}
|
||||
|
||||
gboolean
|
||||
USBSystem::on_source_prepare(GSource* source, gint* timeout)
|
||||
{
|
||||
log_trace();
|
||||
|
||||
struct timeval tv;
|
||||
int ret = libusb_get_next_timeout(NULL, &tv);
|
||||
|
||||
log_debug("libusb_get_next_timeout(): " << ret);
|
||||
|
||||
if (ret == LIBUSB_SUCCESS)
|
||||
{
|
||||
// no timeout
|
||||
}
|
||||
else
|
||||
{
|
||||
// convert tv
|
||||
*timeout = -1;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
USBSystem::on_source_check(GSource* source)
|
||||
{
|
||||
log_trace();
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
USBSystem::on_source_dispatch(GSource* source, GSourceFunc callback, gpointer userdata)
|
||||
{
|
||||
log_trace();
|
||||
return callback(userdata);
|
||||
}
|
||||
|
||||
gboolean
|
||||
USBSystem::on_source()
|
||||
{
|
||||
log_trace();
|
||||
libusb_handle_events(NULL);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* EOF */
|
68
src/usb_system.hpp
Normal file
68
src/usb_system.hpp
Normal file
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
** Xbox360 USB Gamepad Userspace Driver
|
||||
** Copyright (C) 2011 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef HEADER_XBOXDRV_USB_SYSTEM_HPP
|
||||
#define HEADER_XBOXDRV_USB_SYSTEM_HPP
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
class USBSystem
|
||||
{
|
||||
private:
|
||||
GSourceFuncs m_source_funcs;
|
||||
GSource* m_source;
|
||||
gint m_source_id;
|
||||
|
||||
public:
|
||||
USBSystem();
|
||||
~USBSystem();
|
||||
|
||||
void attach(GMainContext* context);
|
||||
|
||||
private:
|
||||
gboolean on_source();
|
||||
|
||||
// libusb callbacks
|
||||
void on_usb_pollfd_added(int fd, short events);
|
||||
void on_usb_pollfd_removed(int fd);
|
||||
|
||||
static gboolean on_source_wrap(void* userdata) {
|
||||
return static_cast<USBSystem*>(userdata)->on_source();
|
||||
}
|
||||
|
||||
static void on_usb_pollfd_added_wrap(int fd, short events, void* userdata) {
|
||||
static_cast<USBSystem*>(userdata)->on_usb_pollfd_added(fd, events);
|
||||
}
|
||||
|
||||
static void on_usb_pollfd_removed_wrap(int fd, void* userdata) {
|
||||
static_cast<USBSystem*>(userdata)->on_usb_pollfd_removed(fd);
|
||||
}
|
||||
|
||||
// glib callbacks
|
||||
static gboolean on_source_prepare(GSource* source, gint* timeout_);
|
||||
static gboolean on_source_check(GSource* source);
|
||||
static gboolean on_source_dispatch(GSource* source, GSourceFunc callback, gpointer userdata);
|
||||
|
||||
private:
|
||||
USBSystem(const USBSystem&);
|
||||
USBSystem& operator=(const USBSystem&);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
/* EOF */
|
|
@ -78,6 +78,20 @@ Xbox360Controller::~Xbox360Controller()
|
|||
usb_release_interface(0);
|
||||
}
|
||||
|
||||
void
|
||||
Xbox360Controller::start()
|
||||
{
|
||||
log_trace();
|
||||
usb_submit_read(endpoint_in, 32);
|
||||
}
|
||||
|
||||
void
|
||||
Xbox360Controller::stop()
|
||||
{
|
||||
log_trace();
|
||||
usb_cancel_read();
|
||||
}
|
||||
|
||||
void
|
||||
Xbox360Controller::set_rumble(uint8_t left, uint8_t right)
|
||||
{
|
||||
|
@ -103,6 +117,8 @@ Xbox360Controller::read(XboxGenericMsg& msg, int timeout)
|
|||
bool
|
||||
Xbox360Controller::parse(uint8_t* data, int len, XboxGenericMsg* msg_out)
|
||||
{
|
||||
log_trace();
|
||||
|
||||
if (len == 0)
|
||||
{
|
||||
// happens with the Xbox360 controller every now and then, just
|
||||
|
|
|
@ -50,6 +50,9 @@ public:
|
|||
bool try_detach);
|
||||
~Xbox360Controller();
|
||||
|
||||
void start();
|
||||
void stop();
|
||||
|
||||
void set_rumble(uint8_t left, uint8_t right);
|
||||
void set_led(uint8_t status);
|
||||
bool read(XboxGenericMsg& msg, int timeout);
|
||||
|
|
75
test/usb_read_thread_test.cpp
Normal file
75
test/usb_read_thread_test.cpp
Normal file
|
@ -0,0 +1,75 @@
|
|||
#include <iostream>
|
||||
#include <libusb.h>
|
||||
#include <stdexcept>
|
||||
|
||||
#include "helper.hpp"
|
||||
#include "usb_helper.hpp"
|
||||
#include "usb_read_thread.hpp"
|
||||
#include "raise_exception.hpp"
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
g_logger.set_log_level(Logger::kDebug);
|
||||
|
||||
int ret = libusb_init(NULL);
|
||||
if (ret != LIBUSB_SUCCESS)
|
||||
{
|
||||
raise_exception(std::runtime_error, "libusb_init() failed: " << usb_strerror(ret));
|
||||
}
|
||||
|
||||
libusb_device_handle* handle = libusb_open_device_with_vid_pid(NULL, 0x045e, 0x028e);
|
||||
|
||||
ret = libusb_claim_interface(handle, 1);
|
||||
|
||||
if (ret != LIBUSB_SUCCESS)
|
||||
{
|
||||
raise_exception(std::runtime_error, "libusb_claim_interface() failed: " << usb_strerror(ret));
|
||||
}
|
||||
|
||||
log_info("handle ok");
|
||||
|
||||
if (!handle)
|
||||
{
|
||||
raise_exception(std::runtime_error, "couldn't find device");
|
||||
}
|
||||
else
|
||||
{
|
||||
log_info("starting usb thread");
|
||||
|
||||
unsigned char data[32];
|
||||
|
||||
USBReadThread thread(handle, 1, 32);
|
||||
|
||||
thread.start_thread();
|
||||
bool shutdown = false;
|
||||
int count = 0;
|
||||
while(!shutdown)
|
||||
{
|
||||
count += 1;
|
||||
int transferred;
|
||||
|
||||
std::cout << count << std::endl;
|
||||
|
||||
if (thread.read(data, sizeof(data), &transferred, 100) != LIBUSB_ERROR_TIMEOUT)
|
||||
{
|
||||
std::cout << count << " " << transferred << " - " << raw2str(data, transferred) << std::endl;
|
||||
}
|
||||
|
||||
|
||||
if (!shutdown && count > 30)
|
||||
{
|
||||
std::cout << "shutdown thread" << std::endl;
|
||||
shutdown = true;
|
||||
|
||||
thread.stop_thread();
|
||||
std::cout << "thread stopped" << std::endl;
|
||||
}
|
||||
|
||||
//usleep(1000 * 10);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* EOF */
|
99
test/usb_system_test.cpp
Normal file
99
test/usb_system_test.cpp
Normal file
|
@ -0,0 +1,99 @@
|
|||
/*
|
||||
** Xbox360 USB Gamepad Userspace Driver
|
||||
** Copyright (C) 2011 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <libusb.h>
|
||||
#include <glib.h>
|
||||
#include <stdexcept>
|
||||
|
||||
#include "log.hpp"
|
||||
#include "raise_exception.hpp"
|
||||
#include "usb_helper.hpp"
|
||||
#include "usb_system.hpp"
|
||||
#include "xbox360_controller.hpp"
|
||||
#include "xboxmsg.hpp"
|
||||
|
||||
libusb_device* get_controller_dev()
|
||||
{
|
||||
libusb_device** list;
|
||||
ssize_t num_devices = libusb_get_device_list(NULL, &list);
|
||||
|
||||
for(ssize_t dev_it = 0; dev_it < num_devices; ++dev_it)
|
||||
{
|
||||
libusb_device* dev = list[dev_it];
|
||||
libusb_device_descriptor desc;
|
||||
|
||||
int ret = libusb_get_device_descriptor(dev, &desc);
|
||||
if (ret != LIBUSB_SUCCESS)
|
||||
{
|
||||
log_warn("libusb_get_device_descriptor() failed: " << usb_strerror(ret));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (desc.idVendor == 0x045e && desc.idProduct == 0x028e)
|
||||
{
|
||||
libusb_ref_device(dev);
|
||||
libusb_free_device_list(list, 1 /* unref_devices */);
|
||||
return dev;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
libusb_free_device_list(list, 1 /* unref_devices */);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void process_msg(const XboxGenericMsg& msg)
|
||||
{
|
||||
log_debug(msg);
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
g_logger.set_log_level(Logger::kDebug);
|
||||
|
||||
//g_type_init();
|
||||
|
||||
int ret = libusb_init(NULL);
|
||||
if (ret != LIBUSB_SUCCESS)
|
||||
{
|
||||
raise_exception(std::runtime_error, "libusb_init() failed: " << usb_strerror(ret));
|
||||
}
|
||||
|
||||
GMainLoop* m_gmain = g_main_loop_new(NULL, FALSE);
|
||||
|
||||
USBSystem usb_system;
|
||||
usb_system.attach(NULL);
|
||||
|
||||
libusb_device* dev = get_controller_dev();
|
||||
assert(dev);
|
||||
Xbox360Controller* controller = new Xbox360Controller(dev,
|
||||
false, false, false,
|
||||
false,
|
||||
false,
|
||||
"",
|
||||
"",
|
||||
false);
|
||||
controller->set_msg_callback(boost::bind(&process_msg, _1));
|
||||
controller->start();
|
||||
g_main_loop_run(m_gmain);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* EOF */
|
Loading…
Add table
Reference in a new issue