Cleaned up subsystem init code, split it into classes (thread cleanup in daemon currently broken)
This commit is contained in:
parent
1e1843e41e
commit
1270ec69f6
14 changed files with 569 additions and 400 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -18,3 +18,4 @@ test/ini_parser_test
|
|||
test/usb_read_thread_test
|
||||
test/usb_system_test
|
||||
xboxdrv
|
||||
incoming/
|
||||
|
|
32
TODO
32
TODO
|
@ -57,6 +57,10 @@ Stuff to do before 0.8.0 release:
|
|||
Checklist
|
||||
=========
|
||||
|
||||
* make dbus optional
|
||||
|
||||
* check force feedback
|
||||
|
||||
* check output when --silent not given
|
||||
|
||||
* check clean shutdown
|
||||
|
@ -86,20 +90,21 @@ Checklist
|
|||
xboxdrv: src/usb_controller.cpp:218: void USBController::on_read_data(libusb_transfer*): Assertion `ret == LIBUSB_SUCCESS' failed.
|
||||
Aborted
|
||||
|
||||
* exceptions in glib main loop might be dangerous
|
||||
* exceptions in glib main loop might be dangerous and not really do what is intended
|
||||
|
||||
* invert y axis on --evdev
|
||||
* move sigint/sigterm handling out of main.cpp and into xboxdrv_daemon.cpp (needs to use gmain_quit())
|
||||
|
||||
* LED do currently not get down on controller quit
|
||||
|
||||
* move LED setting into ControllerThread or somewhere else, not at controller creation time
|
||||
|
||||
* check that threads are cleaned up in daemon
|
||||
|
||||
|
||||
Stuff to do before 0.7.4 release:
|
||||
=================================
|
||||
|
||||
* add double-click button, in the same wayne as hold-button
|
||||
|
||||
* add --controller 4 or --controller-count 4 or something like that
|
||||
|
||||
* add special LED status set switches the LED with the given config
|
||||
* invert y axis on --evdev
|
||||
|
||||
if (opts.priority == Options::kPriorityRealtime)
|
||||
{
|
||||
|
@ -132,6 +137,12 @@ Stuff to do before 0.7.4 release:
|
|||
}
|
||||
}
|
||||
|
||||
* add double-click button, in the same wayne as hold-button
|
||||
|
||||
* add --controller 4 or --controller-count 4 or something like that
|
||||
|
||||
* add special LED status set switches the LED with the given config
|
||||
|
||||
* export build-in config files, both as text and as directory, so that users can browse them
|
||||
|
||||
* deadzone:MIN:MAX:SMOOTH is broken (fixed)
|
||||
|
@ -204,7 +215,7 @@ Here KEY_B is the key you want to send and KEY_A is a random other key
|
|||
that you don't need. It's a hack as mapping both to KEY_B seems to
|
||||
cause some trouble with automatic key repeat for some reason. Note
|
||||
that you must not combine this with --trigger-as-zaxis as that will
|
||||
disable LT and RT
|
||||
disable LT and RT -> already fixed, check it
|
||||
|
||||
* add a "click" filter or something like that, that causes a button to only be clicked, not hold
|
||||
|
||||
|
@ -249,12 +260,7 @@ disable LT and RT
|
|||
-> hard to avoid, as wireless controllers are only picked up when
|
||||
active, which they always become later then the wired ones, which
|
||||
are active by default)
|
||||
|
||||
* add libusb-0.1 support back (maybe only in 0.7.4)
|
||||
-> no, need a full switch
|
||||
|
||||
* move sigint/sigterm handling out of main.cpp and into xboxdrv_daemon.cpp (needs to use gmain_quit())
|
||||
|
||||
* BTN_A@joystick.1 doesn't work for a single joystick, why? (joystick isn't id=0, why?)
|
||||
|
||||
* improve output on which uinput devices are created (even with udev
|
||||
|
|
105
src/dbus_subsystem.cpp
Normal file
105
src/dbus_subsystem.cpp
Normal file
|
@ -0,0 +1,105 @@
|
|||
/*
|
||||
** 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 "dbus_subsystem.hpp"
|
||||
|
||||
#include <boost/format.hpp>
|
||||
#include <dbus/dbus-glib-lowlevel.h>
|
||||
//#include <dbus/dbus-glib-binding.h>
|
||||
#include <dbus/dbus.h>
|
||||
#include <sstream>
|
||||
#include <stdexcept>
|
||||
|
||||
#include "raise_exception.hpp"
|
||||
#include "xboxdrv_g_controller.hpp"
|
||||
#include "xboxdrv_g_daemon.hpp"
|
||||
#include "xboxdrv_daemon_glue.hpp"
|
||||
#include "xboxdrv_controller_glue.hpp"
|
||||
|
||||
DBusSubsystem::DBusSubsystem(const std::string& name) :
|
||||
m_connection()
|
||||
{
|
||||
GError* gerror = NULL;
|
||||
|
||||
// this calls automatically sets up connection to the main loop
|
||||
m_connection = dbus_g_bus_get(DBUS_BUS_SESSION, &gerror);
|
||||
if (!m_connection)
|
||||
{
|
||||
std::ostringstream out;
|
||||
out << "failed to open connection to bus: " << gerror->message;
|
||||
g_error_free(gerror);
|
||||
throw std::runtime_error(out.str());
|
||||
}
|
||||
|
||||
request_name(name);
|
||||
}
|
||||
|
||||
DBusSubsystem::~DBusSubsystem()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
DBusSubsystem::request_name(const std::string& name)
|
||||
{
|
||||
DBusError error;
|
||||
dbus_error_init(&error);
|
||||
|
||||
// FIXME: replace this with org_freedesktop_DBus_request_name()
|
||||
int ret = dbus_bus_request_name(dbus_g_connection_get_connection(m_connection),
|
||||
name.c_str(),
|
||||
DBUS_NAME_FLAG_REPLACE_EXISTING,
|
||||
&error);
|
||||
|
||||
if (dbus_error_is_set(&error))
|
||||
{
|
||||
std::ostringstream out;
|
||||
out << "failed to get unique dbus name: " << error.message;
|
||||
dbus_error_free(&error);
|
||||
throw std::runtime_error(out.str());
|
||||
}
|
||||
|
||||
if (ret != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER)
|
||||
{
|
||||
raise_exception(std::runtime_error, "failed to become primary owner of dbus name");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
DBusSubsystem::register_xboxdrv_daemon(XboxdrvDaemon* c_daemon)
|
||||
{
|
||||
// FIXME: should unref() these somewhere
|
||||
XboxdrvGDaemon* daemon = xboxdrv_g_daemon_new(c_daemon);
|
||||
dbus_g_object_type_install_info(XBOXDRV_TYPE_G_DAEMON, &dbus_glib_xboxdrv_daemon_object_info);
|
||||
dbus_g_connection_register_g_object(m_connection, "/org/seul/Xboxdrv/Daemon", G_OBJECT(daemon));
|
||||
}
|
||||
|
||||
void
|
||||
DBusSubsystem::register_controller_slots(const std::vector<ControllerSlotPtr>& slots)
|
||||
{
|
||||
for(std::vector<ControllerSlotPtr>::const_iterator i = slots.begin(); i != slots.end(); ++i)
|
||||
{
|
||||
XboxdrvGController* controller = xboxdrv_g_controller_new(i->get());
|
||||
dbus_g_object_type_install_info(XBOXDRV_TYPE_G_CONTROLLER, &dbus_glib_xboxdrv_controller_object_info);
|
||||
dbus_g_connection_register_g_object(m_connection,
|
||||
(boost::format("/org/seul/Xboxdrv/ControllerSlots/%d")
|
||||
% (i - slots.begin())).str().c_str(),
|
||||
G_OBJECT(controller));
|
||||
}
|
||||
}
|
||||
|
||||
/* EOF */
|
52
src/dbus_subsystem.hpp
Normal file
52
src/dbus_subsystem.hpp
Normal file
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
** 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_DBUS_SUBSYSTEM_HPP
|
||||
#define HEADER_XBOXDRV_DBUS_SUBSYSTEM_HPP
|
||||
|
||||
#include <dbus/dbus-glib.h>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "controller_slot_ptr.hpp"
|
||||
|
||||
class XboxdrvDaemon;
|
||||
|
||||
class DBusSubsystem
|
||||
{
|
||||
private:
|
||||
DBusGConnection* m_connection;
|
||||
|
||||
public:
|
||||
DBusSubsystem(const std::string& name);
|
||||
~DBusSubsystem();
|
||||
|
||||
void register_xboxdrv_daemon(XboxdrvDaemon* c_daemon);
|
||||
void register_controller_slots(const std::vector<ControllerSlotPtr>& slots);
|
||||
|
||||
private:
|
||||
void request_name(const std::string& name);
|
||||
|
||||
private:
|
||||
DBusSubsystem(const DBusSubsystem&);
|
||||
DBusSubsystem& operator=(const DBusSubsystem&);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
/* EOF */
|
237
src/udev_subsystem.cpp
Normal file
237
src/udev_subsystem.cpp
Normal file
|
@ -0,0 +1,237 @@
|
|||
/*
|
||||
** 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 "udev_subsystem.hpp"
|
||||
|
||||
#include <stdexcept>
|
||||
|
||||
#include "raise_exception.hpp"
|
||||
|
||||
UdevSubsystem::UdevSubsystem() :
|
||||
m_udev(),
|
||||
m_monitor(),
|
||||
m_process_match_cb()
|
||||
{
|
||||
m_udev = udev_new();
|
||||
if (!m_udev)
|
||||
{
|
||||
raise_exception(std::runtime_error, "udev init failure");
|
||||
}
|
||||
}
|
||||
|
||||
UdevSubsystem::~UdevSubsystem()
|
||||
{
|
||||
if (m_monitor)
|
||||
{
|
||||
udev_monitor_unref(m_monitor);
|
||||
}
|
||||
udev_unref(m_udev);
|
||||
}
|
||||
|
||||
void
|
||||
UdevSubsystem::set_device_callback(const boost::function<void (udev_device*)>& process_match_cb)
|
||||
{
|
||||
assert(process_match_cb);
|
||||
assert(!m_process_match_cb);
|
||||
|
||||
m_process_match_cb = process_match_cb;
|
||||
|
||||
// Setup udev monitor and enumerate
|
||||
m_monitor = udev_monitor_new_from_netlink(m_udev, "udev");
|
||||
udev_monitor_filter_add_match_subsystem_devtype(m_monitor, "usb", "usb_device");
|
||||
udev_monitor_enable_receiving(m_monitor);
|
||||
|
||||
// FIXME: won't we get devices twice that have been plugged in at
|
||||
// this point? once from the enumeration, once from the monitor
|
||||
enumerate_udev_devices();
|
||||
|
||||
GIOChannel* udev_channel = g_io_channel_unix_new(udev_monitor_get_fd(m_monitor));
|
||||
g_io_add_watch(udev_channel,
|
||||
static_cast<GIOCondition>(G_IO_IN | G_IO_PRI | G_IO_ERR | G_IO_HUP),
|
||||
&UdevSubsystem::on_udev_data_wrap, this);
|
||||
g_io_channel_unref(udev_channel);
|
||||
}
|
||||
|
||||
void
|
||||
UdevSubsystem::enumerate_udev_devices()
|
||||
{
|
||||
assert(m_process_match_cb);
|
||||
|
||||
// Enumerate over all devices already connected to the computer
|
||||
struct udev_enumerate* enumerate = udev_enumerate_new(m_udev);
|
||||
assert(enumerate);
|
||||
|
||||
udev_enumerate_add_match_subsystem(enumerate, "usb");
|
||||
// not available yet: udev_enumerate_add_match_is_initialized(enumerate);
|
||||
udev_enumerate_scan_devices(enumerate);
|
||||
|
||||
struct udev_list_entry* devices;
|
||||
struct udev_list_entry* dev_list_entry;
|
||||
|
||||
devices = udev_enumerate_get_list_entry(enumerate);
|
||||
udev_list_entry_foreach(dev_list_entry, devices)
|
||||
{
|
||||
// name is path, value is NULL
|
||||
const char* path = udev_list_entry_get_name(dev_list_entry);
|
||||
|
||||
struct udev_device* device = udev_device_new_from_syspath(m_udev, path);
|
||||
|
||||
// manually filter for devtype, as udev enumerate can't do it by itself
|
||||
const char* devtype = udev_device_get_devtype(device);
|
||||
if (devtype && strcmp(devtype, "usb_device") == 0)
|
||||
{
|
||||
m_process_match_cb(device);
|
||||
}
|
||||
udev_device_unref(device);
|
||||
}
|
||||
udev_enumerate_unref(enumerate);
|
||||
}
|
||||
|
||||
bool
|
||||
UdevSubsystem::on_udev_data(GIOChannel* channel, GIOCondition condition)
|
||||
{
|
||||
if (condition == G_IO_OUT)
|
||||
{
|
||||
log_error("data can be written");
|
||||
}
|
||||
else if (condition == G_IO_PRI)
|
||||
{
|
||||
log_error("data can be read");
|
||||
}
|
||||
else if (condition == G_IO_ERR)
|
||||
{
|
||||
log_error("data error");
|
||||
}
|
||||
else if (condition != G_IO_IN)
|
||||
{
|
||||
log_error("unknown condition: " << condition);
|
||||
}
|
||||
else
|
||||
{
|
||||
log_info("trying to read data from udev");
|
||||
|
||||
log_info("trying to read data from udev monitor");
|
||||
struct udev_device* device = udev_monitor_receive_device(m_monitor);
|
||||
log_info("got data from udev monitor");
|
||||
|
||||
if (!device)
|
||||
{
|
||||
// seem to be normal, do we get this when the given device is filtered out?
|
||||
log_debug("udev device couldn't be read: " << device);
|
||||
}
|
||||
else
|
||||
{
|
||||
const char* action = udev_device_get_action(device);
|
||||
|
||||
if (g_logger.get_log_level() >= Logger::kDebug)
|
||||
{
|
||||
print_info(device);
|
||||
}
|
||||
|
||||
if (action && strcmp(action, "add") == 0)
|
||||
{
|
||||
m_process_match_cb(device);
|
||||
}
|
||||
|
||||
udev_device_unref(device);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
UdevSubsystem::print_info(udev_device* device)
|
||||
{
|
||||
log_debug("/---------------------------------------------");
|
||||
log_debug("devpath: " << udev_device_get_devpath(device));
|
||||
|
||||
if (udev_device_get_action(device))
|
||||
log_debug("action: " << udev_device_get_action(device));
|
||||
//log_debug("init: " << udev_device_get_is_initialized(device));
|
||||
|
||||
if (udev_device_get_subsystem(device))
|
||||
log_debug("subsystem: " << udev_device_get_subsystem(device));
|
||||
|
||||
if (udev_device_get_devtype(device))
|
||||
log_debug("devtype: " << udev_device_get_devtype(device));
|
||||
|
||||
if (udev_device_get_syspath(device))
|
||||
log_debug("syspath: " << udev_device_get_syspath(device));
|
||||
|
||||
if (udev_device_get_sysname(device))
|
||||
log_debug("sysname: " << udev_device_get_sysname(device));
|
||||
|
||||
if (udev_device_get_sysnum(device))
|
||||
log_debug("sysnum: " << udev_device_get_sysnum(device));
|
||||
|
||||
if (udev_device_get_devnode(device))
|
||||
log_debug("devnode: " << udev_device_get_devnode(device));
|
||||
|
||||
if (udev_device_get_driver(device))
|
||||
log_debug("driver: " << udev_device_get_driver(device));
|
||||
|
||||
if (udev_device_get_action(device))
|
||||
log_debug("action: " << udev_device_get_action(device));
|
||||
|
||||
//udev_device_get_sysattr_value(device, "busnum");
|
||||
//udev_device_get_sysattr_value(device, "devnum");
|
||||
|
||||
#if 0
|
||||
// FIXME: only works with newer versions of libudev
|
||||
{
|
||||
log_debug("list: ");
|
||||
struct udev_list_entry* it = udev_device_get_tags_list_entry(device);
|
||||
while((it = udev_list_entry_get_next(it)) != 0)
|
||||
{
|
||||
log_debug(" "
|
||||
<< udev_list_entry_get_name(it) << " = "
|
||||
<< udev_list_entry_get_value(it)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
log_debug("properties: ");
|
||||
struct udev_list_entry* it = udev_device_get_properties_list_entry(device);
|
||||
while((it = udev_list_entry_get_next(it)) != 0)
|
||||
{
|
||||
log_debug(" "
|
||||
<< udev_list_entry_get_name(it) << " = "
|
||||
<< udev_list_entry_get_value(it)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
log_debug("devlist: ");
|
||||
struct udev_list_entry* it = udev_device_get_tags_list_entry(device);
|
||||
while((it = udev_list_entry_get_next(it)) != 0)
|
||||
{
|
||||
log_debug(" "
|
||||
<< udev_list_entry_get_name(it) << " = "
|
||||
<< udev_list_entry_get_value(it)
|
||||
);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
log_debug("\\----------------------------------------------");
|
||||
}
|
||||
|
||||
/* EOF */
|
56
src/udev_subsystem.hpp
Normal file
56
src/udev_subsystem.hpp
Normal file
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
** 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_UDEV_SUBSYSTEM_HPP
|
||||
#define HEADER_XBOXDRV_UDEV_SUBSYSTEM_HPP
|
||||
|
||||
#include <boost/function.hpp>
|
||||
#include <libudev.h>
|
||||
#include <glib.h>
|
||||
|
||||
class UdevSubsystem
|
||||
{
|
||||
private:
|
||||
struct udev* m_udev;
|
||||
struct udev_monitor* m_monitor;
|
||||
|
||||
boost::function<void (udev_device*)> m_process_match_cb;
|
||||
|
||||
public:
|
||||
UdevSubsystem();
|
||||
~UdevSubsystem();
|
||||
|
||||
void set_device_callback(const boost::function<void (udev_device*)>& process_match_cb);
|
||||
void enumerate_udev_devices();
|
||||
void print_info(udev_device* device);
|
||||
|
||||
private:
|
||||
bool on_udev_data(GIOChannel* channel, GIOCondition condition);
|
||||
|
||||
static gboolean on_udev_data_wrap(GIOChannel* channel, GIOCondition condition, gpointer data) {
|
||||
return static_cast<UdevSubsystem*>(data)->on_udev_data(channel, condition);
|
||||
}
|
||||
|
||||
private:
|
||||
UdevSubsystem(const UdevSubsystem&);
|
||||
UdevSubsystem& operator=(const UdevSubsystem&);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
/* EOF */
|
|
@ -21,10 +21,30 @@
|
|||
#include <stdexcept>
|
||||
#include <boost/format.hpp>
|
||||
|
||||
#include "usb_helper.hpp"
|
||||
#include "options.hpp"
|
||||
#include "raise_exception.hpp"
|
||||
#include "usb_gsource.hpp"
|
||||
#include "usb_helper.hpp"
|
||||
|
||||
USBSubsystem::USBSubsystem() :
|
||||
m_usb_gsource()
|
||||
{
|
||||
int ret = libusb_init(NULL);
|
||||
if (ret != LIBUSB_SUCCESS)
|
||||
{
|
||||
raise_exception(std::runtime_error, "libusb_init() failed: " << usb_strerror(ret));
|
||||
}
|
||||
|
||||
m_usb_gsource.reset(new USBGSource);
|
||||
m_usb_gsource->attach(NULL);
|
||||
}
|
||||
|
||||
USBSubsystem::~USBSubsystem()
|
||||
{
|
||||
m_usb_gsource.reset();
|
||||
libusb_exit(NULL);
|
||||
}
|
||||
|
||||
void
|
||||
USBSubsystem::find_controller(libusb_device** dev, XPadDevice& dev_type, const Options& opts)
|
||||
{
|
||||
|
|
|
@ -20,17 +20,23 @@
|
|||
#define HEADER_XBOXDRV_USB_SUBSYSTEM_HPP
|
||||
|
||||
#include <libusb.h>
|
||||
#include <boost/scoped_ptr.hpp>
|
||||
|
||||
#include "xpad_device.hpp"
|
||||
|
||||
class USBGSource;
|
||||
class Options;
|
||||
|
||||
class USBSubsystem
|
||||
{
|
||||
private:
|
||||
boost::scoped_ptr<USBGSource> m_usb_gsource;
|
||||
|
||||
public:
|
||||
USBSubsystem();
|
||||
|
||||
~USBSubsystem();
|
||||
|
||||
public:
|
||||
static void find_controller(libusb_device** dev, XPadDevice& dev_type, const Options& opts);
|
||||
static bool find_controller_by_path(const std::string& busid, const std::string& devid,
|
||||
libusb_device** xbox_device);
|
||||
|
|
|
@ -96,8 +96,6 @@ Xbox360Controller::set_led(uint8_t status)
|
|||
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
|
||||
|
|
|
@ -204,12 +204,6 @@ Xboxdrv::run_daemon(const Options& opts)
|
|||
print_copyright();
|
||||
}
|
||||
|
||||
int ret = libusb_init(NULL);
|
||||
if (ret != LIBUSB_SUCCESS)
|
||||
{
|
||||
raise_exception(std::runtime_error, "libusb_init() failed: " << usb_strerror(ret));
|
||||
}
|
||||
|
||||
if (opts.usb_debug)
|
||||
{
|
||||
libusb_set_debug(NULL, 3);
|
||||
|
@ -254,8 +248,6 @@ Xboxdrv::run_daemon(const Options& opts)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
libusb_exit(NULL);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -34,10 +34,9 @@
|
|||
#include "controller_factory.hpp"
|
||||
#include "controller_slot.hpp"
|
||||
#include "controller.hpp"
|
||||
#include "xboxdrv_g_daemon.hpp"
|
||||
#include "xboxdrv_g_controller.hpp"
|
||||
#include "xboxdrv_daemon_glue.hpp"
|
||||
#include "xboxdrv_controller_glue.hpp"
|
||||
#include "udev_subsystem.hpp"
|
||||
#include "dbus_subsystem.hpp"
|
||||
#include "usb_subsystem.hpp"
|
||||
|
||||
XboxdrvDaemon* XboxdrvDaemon::s_current = 0;
|
||||
|
||||
|
@ -98,16 +97,19 @@ bool get_usb_path(udev_device* device, int* bus, int* dev)
|
|||
|
||||
XboxdrvDaemon::XboxdrvDaemon(const Options& opts) :
|
||||
m_opts(opts),
|
||||
m_udev(0),
|
||||
m_monitor(0),
|
||||
m_usb_gsource(),
|
||||
m_gmain(),
|
||||
m_controller_slots(),
|
||||
m_inactive_controllers(),
|
||||
m_uinput(),
|
||||
m_gmain()
|
||||
m_uinput()
|
||||
{
|
||||
assert(!s_current);
|
||||
s_current = this;
|
||||
|
||||
g_type_init();
|
||||
m_gmain = g_main_loop_new(NULL, false);
|
||||
|
||||
signal(SIGINT, &XboxdrvDaemon::on_sigint);
|
||||
signal(SIGTERM, &XboxdrvDaemon::on_sigint);
|
||||
}
|
||||
|
||||
XboxdrvDaemon::~XboxdrvDaemon()
|
||||
|
@ -125,8 +127,34 @@ XboxdrvDaemon::~XboxdrvDaemon()
|
|||
}
|
||||
}
|
||||
|
||||
udev_monitor_unref(m_monitor);
|
||||
udev_unref(m_udev);
|
||||
g_main_loop_unref(m_gmain);
|
||||
}
|
||||
|
||||
void
|
||||
XboxdrvDaemon::run()
|
||||
{
|
||||
try
|
||||
{
|
||||
create_pid_file();
|
||||
|
||||
init_uinput();
|
||||
|
||||
USBSubsystem usb_subsystem;
|
||||
|
||||
UdevSubsystem udev_subsystem;
|
||||
udev_subsystem.set_device_callback(boost::bind(&XboxdrvDaemon::process_match, this, _1));
|
||||
|
||||
DBusSubsystem dbus_subsystem("org.seul.Xboxdrv");
|
||||
dbus_subsystem.register_xboxdrv_daemon(this);
|
||||
dbus_subsystem.register_controller_slots(m_controller_slots);
|
||||
|
||||
log_debug("launching into main loop");
|
||||
g_main_loop_run(m_gmain);
|
||||
}
|
||||
catch(const std::exception& err)
|
||||
{
|
||||
log_error("fatal exception: " << err.what());
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -156,6 +184,9 @@ XboxdrvDaemon::cleanup_threads()
|
|||
void
|
||||
XboxdrvDaemon::process_match(struct udev_device* device)
|
||||
{
|
||||
// FIXME: bad place?!
|
||||
// FIXME: cleanup_threads();
|
||||
|
||||
uint16_t vendor;
|
||||
uint16_t product;
|
||||
|
||||
|
@ -239,65 +270,6 @@ XboxdrvDaemon::init_uinput()
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
XboxdrvDaemon::init_udev()
|
||||
{
|
||||
assert(!m_udev);
|
||||
|
||||
m_udev = udev_new();
|
||||
|
||||
if (!m_udev)
|
||||
{
|
||||
raise_exception(std::runtime_error, "udev init failure");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
XboxdrvDaemon::init_udev_monitor()
|
||||
{
|
||||
// Setup udev monitor and enumerate
|
||||
m_monitor = udev_monitor_new_from_netlink(m_udev, "udev");
|
||||
udev_monitor_filter_add_match_subsystem_devtype(m_monitor, "usb", "usb_device");
|
||||
udev_monitor_enable_receiving(m_monitor);
|
||||
|
||||
// FIXME: won't we get devices twice that have been plugged in at
|
||||
// this point? once from the enumeration, once from the monitor
|
||||
enumerate_udev_devices();
|
||||
}
|
||||
|
||||
void
|
||||
XboxdrvDaemon::enumerate_udev_devices()
|
||||
{
|
||||
// Enumerate over all devices already connected to the computer
|
||||
struct udev_enumerate* enumerate = udev_enumerate_new(m_udev);
|
||||
assert(enumerate);
|
||||
|
||||
udev_enumerate_add_match_subsystem(enumerate, "usb");
|
||||
// not available yet: udev_enumerate_add_match_is_initialized(enumerate);
|
||||
udev_enumerate_scan_devices(enumerate);
|
||||
|
||||
struct udev_list_entry* devices;
|
||||
struct udev_list_entry* dev_list_entry;
|
||||
|
||||
devices = udev_enumerate_get_list_entry(enumerate);
|
||||
udev_list_entry_foreach(dev_list_entry, devices)
|
||||
{
|
||||
// name is path, value is NULL
|
||||
const char* path = udev_list_entry_get_name(dev_list_entry);
|
||||
|
||||
struct udev_device* device = udev_device_new_from_syspath(m_udev, path);
|
||||
|
||||
// manually filter for devtype, as udev enumerate can't do it by itself
|
||||
const char* devtype = udev_device_get_devtype(device);
|
||||
if (devtype && strcmp(devtype, "usb_device") == 0)
|
||||
{
|
||||
process_match(device);
|
||||
}
|
||||
udev_device_unref(device);
|
||||
}
|
||||
udev_enumerate_unref(enumerate);
|
||||
}
|
||||
|
||||
void
|
||||
XboxdrvDaemon::create_pid_file()
|
||||
{
|
||||
|
@ -316,123 +288,6 @@ XboxdrvDaemon::create_pid_file()
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
XboxdrvDaemon::init_g_usb()
|
||||
{
|
||||
assert(!m_usb_gsource);
|
||||
|
||||
m_usb_gsource.reset(new USBGSource);
|
||||
m_usb_gsource->attach(NULL);
|
||||
}
|
||||
|
||||
void
|
||||
XboxdrvDaemon::init_g_udev()
|
||||
{
|
||||
GIOChannel* udev_channel = g_io_channel_unix_new(udev_monitor_get_fd(m_monitor));
|
||||
g_io_add_watch(udev_channel,
|
||||
static_cast<GIOCondition>(G_IO_IN | G_IO_PRI | G_IO_ERR | G_IO_HUP),
|
||||
&XboxdrvDaemon::on_udev_data_wrap, this);
|
||||
g_io_channel_unref(udev_channel);
|
||||
}
|
||||
|
||||
void
|
||||
XboxdrvDaemon::init_g_dbus()
|
||||
{
|
||||
if (m_opts.dbus)
|
||||
{
|
||||
try
|
||||
{
|
||||
GError* gerror = NULL;
|
||||
// this calls automatically sets up connection to the main loop
|
||||
DBusGConnection* connection = dbus_g_bus_get(DBUS_BUS_SESSION, &gerror);
|
||||
if (!connection)
|
||||
{
|
||||
std::ostringstream out;
|
||||
out << "failed to open connection to bus: " << gerror->message;
|
||||
g_error_free(gerror);
|
||||
throw std::runtime_error(out.str());
|
||||
}
|
||||
else
|
||||
{
|
||||
DBusError error;
|
||||
dbus_error_init(&error);
|
||||
int ret = dbus_bus_request_name(dbus_g_connection_get_connection(connection),
|
||||
"org.seul.Xboxdrv",
|
||||
DBUS_NAME_FLAG_REPLACE_EXISTING,
|
||||
&error);
|
||||
|
||||
if (dbus_error_is_set(&error))
|
||||
{
|
||||
std::ostringstream out;
|
||||
out << "failed to get unique dbus name: " << error.message;
|
||||
dbus_error_free(&error);
|
||||
throw std::runtime_error(out.str());
|
||||
}
|
||||
|
||||
if (ret != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER)
|
||||
{
|
||||
raise_exception(std::runtime_error, "failed to become primary owner of dbus name");
|
||||
}
|
||||
|
||||
// FIXME: should unref() these somewhere
|
||||
XboxdrvGDaemon* daemon = xboxdrv_g_daemon_new(this);
|
||||
dbus_g_object_type_install_info(XBOXDRV_TYPE_G_DAEMON, &dbus_glib_xboxdrv_daemon_object_info);
|
||||
dbus_g_connection_register_g_object(connection, "/org/seul/Xboxdrv/Daemon", G_OBJECT(daemon));
|
||||
|
||||
for(ControllerSlots::iterator i = m_controller_slots.begin(); i != m_controller_slots.end(); ++i)
|
||||
{
|
||||
XboxdrvGController* controller = xboxdrv_g_controller_new(i->get());
|
||||
dbus_g_object_type_install_info(XBOXDRV_TYPE_G_CONTROLLER, &dbus_glib_xboxdrv_controller_object_info);
|
||||
dbus_g_connection_register_g_object(connection,
|
||||
(boost::format("/org/seul/Xboxdrv/ControllerSlots/%d") % (i - m_controller_slots.begin())).str().c_str(),
|
||||
G_OBJECT(controller));
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (const std::exception& err)
|
||||
{
|
||||
log_error("D-Bus initialisation failed: " << err.what());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
XboxdrvDaemon::run()
|
||||
{
|
||||
try
|
||||
{
|
||||
create_pid_file();
|
||||
|
||||
init_uinput();
|
||||
init_udev();
|
||||
init_udev_monitor();
|
||||
|
||||
g_type_init();
|
||||
|
||||
// we don't use glib threads, but we still need to init the thread
|
||||
// system to make glib thread safe
|
||||
g_thread_init(NULL);
|
||||
|
||||
signal(SIGINT, &XboxdrvDaemon::on_sigint);
|
||||
signal(SIGTERM, &XboxdrvDaemon::on_sigint);
|
||||
m_gmain = g_main_loop_new(NULL, false);
|
||||
|
||||
init_g_usb();
|
||||
init_g_udev();
|
||||
init_g_dbus();
|
||||
|
||||
log_info("launching into glib main loop");
|
||||
g_main_loop_run(m_gmain);
|
||||
log_info("glib main loop finished");
|
||||
signal(SIGINT, 0);
|
||||
g_main_loop_unref(m_gmain);
|
||||
}
|
||||
catch(const std::exception& err)
|
||||
{
|
||||
log_error("fatal exception: " << err.what());
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
XboxdrvDaemon::on_wakeup()
|
||||
{
|
||||
|
@ -442,60 +297,6 @@ XboxdrvDaemon::on_wakeup()
|
|||
return false; // remove the registered idle callback
|
||||
}
|
||||
|
||||
bool
|
||||
XboxdrvDaemon::on_udev_data(GIOChannel* channel, GIOCondition condition)
|
||||
{
|
||||
if (condition == G_IO_OUT)
|
||||
{
|
||||
log_error("data can be written");
|
||||
}
|
||||
else if (condition == G_IO_PRI)
|
||||
{
|
||||
log_error("data can be read");
|
||||
}
|
||||
else if (condition == G_IO_ERR)
|
||||
{
|
||||
log_error("data error");
|
||||
}
|
||||
else if (condition != G_IO_IN)
|
||||
{
|
||||
log_error("unknown condition: " << condition);
|
||||
}
|
||||
else
|
||||
{
|
||||
log_info("trying to read data from udev");
|
||||
cleanup_threads();
|
||||
|
||||
log_info("trying to read data from udev monitor");
|
||||
struct udev_device* device = udev_monitor_receive_device(m_monitor);
|
||||
log_info("got data from udev monitor");
|
||||
|
||||
if (!device)
|
||||
{
|
||||
// seem to be normal, do we get this when the given device is filtered out?
|
||||
log_debug("udev device couldn't be read: " << device);
|
||||
}
|
||||
else
|
||||
{
|
||||
const char* action = udev_device_get_action(device);
|
||||
|
||||
if (g_logger.get_log_level() >= Logger::kDebug)
|
||||
{
|
||||
print_info(device);
|
||||
}
|
||||
|
||||
if (action && strcmp(action, "add") == 0)
|
||||
{
|
||||
process_match(device);
|
||||
}
|
||||
|
||||
udev_device_unref(device);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
XboxdrvDaemon::check_thread_status()
|
||||
{
|
||||
|
@ -543,85 +344,6 @@ XboxdrvDaemon::check_thread_status()
|
|||
m_inactive_controllers.end());
|
||||
}
|
||||
|
||||
void
|
||||
XboxdrvDaemon::print_info(udev_device* device)
|
||||
{
|
||||
log_debug("/---------------------------------------------");
|
||||
log_debug("devpath: " << udev_device_get_devpath(device));
|
||||
|
||||
if (udev_device_get_action(device))
|
||||
log_debug("action: " << udev_device_get_action(device));
|
||||
//log_debug("init: " << udev_device_get_is_initialized(device));
|
||||
|
||||
if (udev_device_get_subsystem(device))
|
||||
log_debug("subsystem: " << udev_device_get_subsystem(device));
|
||||
|
||||
if (udev_device_get_devtype(device))
|
||||
log_debug("devtype: " << udev_device_get_devtype(device));
|
||||
|
||||
if (udev_device_get_syspath(device))
|
||||
log_debug("syspath: " << udev_device_get_syspath(device));
|
||||
|
||||
if (udev_device_get_sysname(device))
|
||||
log_debug("sysname: " << udev_device_get_sysname(device));
|
||||
|
||||
if (udev_device_get_sysnum(device))
|
||||
log_debug("sysnum: " << udev_device_get_sysnum(device));
|
||||
|
||||
if (udev_device_get_devnode(device))
|
||||
log_debug("devnode: " << udev_device_get_devnode(device));
|
||||
|
||||
if (udev_device_get_driver(device))
|
||||
log_debug("driver: " << udev_device_get_driver(device));
|
||||
|
||||
if (udev_device_get_action(device))
|
||||
log_debug("action: " << udev_device_get_action(device));
|
||||
|
||||
//udev_device_get_sysattr_value(device, "busnum");
|
||||
//udev_device_get_sysattr_value(device, "devnum");
|
||||
|
||||
#if 0
|
||||
// FIXME: only works with newer versions of libudev
|
||||
{
|
||||
log_debug("list: ");
|
||||
struct udev_list_entry* it = udev_device_get_tags_list_entry(device);
|
||||
while((it = udev_list_entry_get_next(it)) != 0)
|
||||
{
|
||||
log_debug(" "
|
||||
<< udev_list_entry_get_name(it) << " = "
|
||||
<< udev_list_entry_get_value(it)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
log_debug("properties: ");
|
||||
struct udev_list_entry* it = udev_device_get_properties_list_entry(device);
|
||||
while((it = udev_list_entry_get_next(it)) != 0)
|
||||
{
|
||||
log_debug(" "
|
||||
<< udev_list_entry_get_name(it) << " = "
|
||||
<< udev_list_entry_get_value(it)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
log_debug("devlist: ");
|
||||
struct udev_list_entry* it = udev_device_get_tags_list_entry(device);
|
||||
while((it = udev_list_entry_get_next(it)) != 0)
|
||||
{
|
||||
log_debug(" "
|
||||
<< udev_list_entry_get_name(it) << " = "
|
||||
<< udev_list_entry_get_value(it)
|
||||
);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
log_debug("\\----------------------------------------------");
|
||||
}
|
||||
|
||||
ControllerSlotPtr
|
||||
XboxdrvDaemon::find_free_slot(udev_device* dev)
|
||||
{
|
||||
|
|
|
@ -37,13 +37,10 @@ class XboxdrvDaemon
|
|||
private:
|
||||
static XboxdrvDaemon* s_current;
|
||||
|
||||
private:
|
||||
const Options& m_opts;
|
||||
|
||||
struct udev* m_udev;
|
||||
struct udev_monitor* m_monitor;
|
||||
GMainLoop* m_gmain;
|
||||
|
||||
boost::scoped_ptr<USBGSource> m_usb_gsource;
|
||||
|
||||
typedef std::vector<ControllerSlotPtr> ControllerSlots;
|
||||
ControllerSlots m_controller_slots;
|
||||
|
||||
|
@ -51,7 +48,6 @@ private:
|
|||
Controllers m_inactive_controllers;
|
||||
|
||||
std::auto_ptr<UInput> m_uinput;
|
||||
GMainLoop* m_gmain;
|
||||
|
||||
private:
|
||||
static void on_sigint(int);
|
||||
|
@ -69,16 +65,9 @@ public:
|
|||
private:
|
||||
void create_pid_file();
|
||||
void init_uinput();
|
||||
void init_udev();
|
||||
void init_udev_monitor();
|
||||
|
||||
void init_g_usb();
|
||||
void init_g_udev();
|
||||
void init_g_dbus();
|
||||
|
||||
ControllerSlotPtr find_free_slot(udev_device* dev);
|
||||
|
||||
void enumerate_udev_devices();
|
||||
void cleanup_threads();
|
||||
void process_match(struct udev_device* device);
|
||||
void print_info(struct udev_device* device);
|
||||
|
@ -98,17 +87,10 @@ private:
|
|||
|
||||
private:
|
||||
bool on_wakeup();
|
||||
bool on_udev_data(GIOChannel* channel, GIOCondition condition);
|
||||
|
||||
private:
|
||||
static gboolean on_wakeup_wrap(gpointer data) {
|
||||
return static_cast<XboxdrvDaemon*>(data)->on_wakeup();
|
||||
}
|
||||
|
||||
static gboolean on_udev_data_wrap(GIOChannel* channel, GIOCondition condition, gpointer data) {
|
||||
return static_cast<XboxdrvDaemon*>(data)->on_udev_data(channel, condition);
|
||||
}
|
||||
|
||||
private:
|
||||
XboxdrvDaemon(const XboxdrvDaemon&);
|
||||
XboxdrvDaemon& operator=(const XboxdrvDaemon&);
|
||||
|
|
|
@ -41,12 +41,20 @@
|
|||
|
||||
XboxdrvMain::XboxdrvMain(const Options& opts) :
|
||||
m_opts(opts),
|
||||
m_gmain(),
|
||||
m_usb_gsource(),
|
||||
m_uinput(),
|
||||
m_jsdev_number(),
|
||||
m_evdev_number(),
|
||||
m_use_libusb(false),
|
||||
m_dev_type()
|
||||
{
|
||||
m_gmain = g_main_loop_new(NULL, false);
|
||||
}
|
||||
|
||||
XboxdrvMain::~XboxdrvMain()
|
||||
{
|
||||
g_main_loop_unref(m_gmain);
|
||||
}
|
||||
|
||||
ControllerPtr
|
||||
|
@ -68,17 +76,6 @@ XboxdrvMain::create_controller()
|
|||
}
|
||||
else
|
||||
{ // regular USB Xbox360 controller
|
||||
m_use_libusb = true;
|
||||
int ret = libusb_init(NULL);
|
||||
if (ret != LIBUSB_SUCCESS)
|
||||
{
|
||||
raise_exception(std::runtime_error, "libusb_init() failed: " << usb_strerror(ret));
|
||||
}
|
||||
|
||||
if (m_opts.usb_debug)
|
||||
{
|
||||
libusb_set_debug(NULL, 3);
|
||||
}
|
||||
|
||||
// FIXME: this must be libusb_unref_device()'ed, child code must not keep a copy around
|
||||
libusb_device* dev = 0;
|
||||
|
@ -125,6 +122,8 @@ XboxdrvMain::init_controller(const ControllerPtr& controller)
|
|||
void
|
||||
XboxdrvMain::run()
|
||||
{
|
||||
USBSubsystem usb_subsystem;
|
||||
|
||||
ControllerPtr controller = create_controller();
|
||||
std::auto_ptr<MessageProcessor> message_proc;
|
||||
init_controller(controller);
|
||||
|
@ -141,25 +140,27 @@ XboxdrvMain::run()
|
|||
if (m_opts.no_uinput)
|
||||
{
|
||||
if (!m_opts.quiet)
|
||||
{
|
||||
std::cout << "Starting without uinput" << std::endl;
|
||||
}
|
||||
|
||||
message_proc.reset(new DummyMessageProcessor);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!m_opts.quiet)
|
||||
std::cout << "Starting with uinput" << std::endl;
|
||||
|
||||
log_debug("creating UInput");
|
||||
m_uinput.reset(new UInput(m_opts.extra_events));
|
||||
m_uinput->set_device_names(m_opts.uinput_device_names);
|
||||
m_uinput->set_device_usbids(m_opts.uinput_device_usbids);
|
||||
|
||||
log_debug("creating ControllerSlotConfig");
|
||||
ControllerSlotConfigPtr config_set = ControllerSlotConfig::create(*m_uinput,
|
||||
0, m_opts.extra_devices,
|
||||
m_opts.get_controller_slot());
|
||||
|
||||
// After all the ControllerConfig registered their events, finish up
|
||||
// the device creation
|
||||
log_debug("finish UInput creation");
|
||||
m_uinput->finish();
|
||||
|
||||
message_proc.reset(new UInputMessageProcessor(*m_uinput, config_set, m_opts));
|
||||
|
@ -181,15 +182,7 @@ XboxdrvMain::run()
|
|||
}
|
||||
}
|
||||
|
||||
GMainLoop* m_gmain = g_main_loop_new(NULL, false);
|
||||
{
|
||||
boost::scoped_ptr<USBGSource> usb_gsource;
|
||||
if (m_use_libusb)
|
||||
{
|
||||
usb_gsource.reset(new USBGSource);
|
||||
usb_gsource->attach(NULL);
|
||||
}
|
||||
|
||||
ControllerThread thread(controller, message_proc, m_opts);
|
||||
log_debug("launching thread");
|
||||
|
||||
|
@ -202,12 +195,6 @@ XboxdrvMain::run()
|
|||
log_debug("launching main loop");
|
||||
g_main_loop_run(m_gmain);
|
||||
}
|
||||
g_main_loop_unref(m_gmain);
|
||||
|
||||
if (m_use_libusb)
|
||||
{
|
||||
libusb_exit(NULL);
|
||||
}
|
||||
|
||||
if (!m_opts.quiet)
|
||||
{
|
||||
|
@ -226,16 +213,14 @@ XboxdrvMain::print_info(libusb_device* dev, const XPadDevice& dev_type, const Op
|
|||
raise_exception(std::runtime_error, "libusb_get_device_descriptor() failed: " << usb_strerror(ret));
|
||||
}
|
||||
|
||||
std::cout << "USB Device: " << boost::format("%03d:%03d")
|
||||
% static_cast<int>(libusb_get_bus_number(dev))
|
||||
% static_cast<int>(libusb_get_device_address(dev)) << std::endl;
|
||||
std::cout << "Controller: " << dev_type.name << std::endl;
|
||||
std::cout << "Vendor/Product: " << boost::format("%04x:%04x")
|
||||
% uint16_t(desc.idVendor) % uint16_t(desc.idProduct) << std::endl;
|
||||
std::cout << "USB Path: " << boost::format("%03d:%03d")
|
||||
% static_cast<int>(libusb_get_bus_number(dev))
|
||||
% static_cast<int>(libusb_get_device_address(dev)) << std::endl;
|
||||
if (dev_type.type == GAMEPAD_XBOX360_WIRELESS)
|
||||
std::cout << "Wireless Port: " << opts.wireless_id << std::endl;
|
||||
else
|
||||
std::cout << "Wireless Port: -" << std::endl;
|
||||
std::cout << "Controller Type: " << dev_type.type << std::endl;
|
||||
|
||||
//std::cout << "ForceFeedback: " << ((opts.controller.back().uinput.force_feedback) ? "enabled" : "disabled") << std::endl;
|
||||
|
|
|
@ -21,18 +21,24 @@
|
|||
|
||||
#include <memory>
|
||||
#include <libusb.h>
|
||||
#include <glib.h>
|
||||
#include <boost/scoped_ptr.hpp>
|
||||
|
||||
#include "xpad_device.hpp"
|
||||
#include "controller_ptr.hpp"
|
||||
|
||||
class UInput;
|
||||
class Options;
|
||||
class MessageProcessor;
|
||||
class Options;
|
||||
class UInput;
|
||||
class USBGSource;
|
||||
|
||||
class XboxdrvMain
|
||||
{
|
||||
private:
|
||||
const Options& m_opts;
|
||||
GMainLoop* m_gmain;
|
||||
boost::scoped_ptr<USBGSource> m_usb_gsource;
|
||||
|
||||
std::auto_ptr<UInput> m_uinput;
|
||||
|
||||
int m_jsdev_number;
|
||||
|
@ -43,6 +49,7 @@ private:
|
|||
|
||||
public:
|
||||
XboxdrvMain(const Options& opts);
|
||||
~XboxdrvMain();
|
||||
void run();
|
||||
|
||||
private:
|
||||
|
|
Loading…
Reference in a new issue