Added -d, --detach-kernel-driver option

This commit is contained in:
Ingo Ruhnke 2010-05-30 14:49:32 +02:00
parent 483e598f86
commit a429856889
18 changed files with 98 additions and 30 deletions

2
NEWS
View file

@ -3,7 +3,7 @@ xboxdrv 0.6.0 - (??/Jun/2010)
* support for reading from evdev, this allows the use of regular
regular PC joysticks with xboxdrv, useful if you need
configurability or joy2key like functionality, but don't have a
configurability or joy2key-like functionality, but don't have a
Xbox360 gamepad

27
TODO
View file

@ -12,8 +12,31 @@ git archive --format=tar --prefix="xboxdrv-linux-${VERSION}/" ${TAG} | bzip2 -c
git push --tags
Stuff to do before 0.5.1 release:
===============================
Stuff to do before 0.6.0 release:
=================================
* need support for numbers, not just names in evdev_helper, need special syntax to get the type:
KEY_1 is not unique, maybe: KEYNUM_1, ABSNUM_1, ...
* axis-min/max range must be transmitted to AxisEvent (maybe normalize to float)
* match by protocol not, just vendor/product, from xpad.c:
/* Xbox 360 has a vendor-specific class, so we cannot match it with only
* USB_INTERFACE_INFO (also specifically refused by USB subsystem), so we
* match against vendor id as well. Wired Xbox 360 devices have protocol 1,
* wireless controllers have protocol 129. */
#define XPAD_XBOX360_VENDOR_PROTOCOL(vend,pr) \
.match_flags = USB_DEVICE_ID_MATCH_VENDOR | USB_DEVICE_ID_MATCH_INT_INFO, \
.idVendor = (vend), \
.bInterfaceClass = USB_CLASS_VENDOR_SPEC, \
.bInterfaceSubClass = 93, \
.bInterfaceProtocol = (pr)
#define XPAD_XBOX360_VENDOR(vend) \
{ XPAD_XBOX360_VENDOR_PROTOCOL(vend,1) }, \
{ XPAD_XBOX360_VENDOR_PROTOCOL(vend,129) }
Docu
====

View file

@ -1 +1 @@
0.5.0
0.6.0

View file

@ -102,6 +102,12 @@ a way to launch \fBxboxdrv\fR
automatically.
.SS "DEVICE OPTIONS"
.TP
\*(T<\fB\-d\fR\*(T>, \*(T<\fB\-\-detach\-kernel\-driver\fR\*(T>
Detaches the kernel driver that is currently associated
with the given device. This is useful when you have the
xpad module loaded and want to use xboxdrv without
unloading it.
.TP
\*(T<\fB\-i\fR\*(T>, \*(T<\fB\-\-id\fR\*(T> \fIN\fR
Use controller with id N (default: 0),
use \*(T<\fB\-\-list\-controller\fR\*(T> to obtain a list

View file

@ -214,6 +214,18 @@
<refsect2>
<title>Device Options</title>
<variablelist>
<varlistentry>
<term><option>-d</option>, <option>--detach-kernel-driver</option></term>
<listitem>
<para>
Detaches the kernel driver that is currently associated
with the given device. This is useful when you have the
xpad module loaded and want to use xboxdrv without
unloading it.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>-i</option>, <option>--id</option> <replaceable class="parameter">N</replaceable></term>
<listitem>

View file

@ -81,6 +81,7 @@ enum {
OPTION_EVDEV,
OPTION_EVDEV_ABSMAP,
OPTION_EVDEV_KEYMAP,
OPTION_DETACH_KERNEL_DRIVER,
OPTION_HELP_DEVICES
};
@ -144,6 +145,7 @@ CommandLineOptions::CommandLineOptions() :
.add_newline()
.add_text("Device Options: ")
.add_option(OPTION_DETACH_KERNEL_DRIVER, 'd', "detach-kernel-driver", "", "Detaches the kernel driver currently associated with the device")
.add_option(OPTION_ID, 'i', "id", "N", "use controller with id N (default: 0)")
.add_option(OPTION_WID, 'w', "wid", "N", "use wireless controller with wid N (default: 0)")
.add_option(OPTION_DEVICE_BY_PATH, 0, "device-by-path", "BUS:DEV", "Use device BUS:DEV, do not do any scanning")
@ -424,6 +426,10 @@ CommandLineOptions::parse_args(int argc, char** argv)
boost::bind(&set_ui_button_map, boost::ref(opts.uinput_config.btn_map), _1));
break;
case OPTION_DETACH_KERNEL_DRIVER:
opts.detach_kernel_driver = true;
break;
case OPTION_EVDEV:
opts.evdev_device = opt.argument;
break;

View file

@ -209,6 +209,8 @@ EvdevController::read(XboxGenericMsg& msg, bool verbose, int timeout)
}
}
usleep(timeout * 1000);
return false;
}

View file

@ -23,6 +23,7 @@
#include <sstream>
#include <stdexcept>
#include <map>
#include <ctype.h>
#include "enum_box.hpp"
#include "evdev_helper.hpp"
@ -674,6 +675,18 @@ int get_event_type(const std::string& name)
}
}
bool is_number_(const std::string& name)
{
for(std::string::const_iterator i = name.begin(); i != name.end(); ++i)
{
if (!isdigit(*i))
{
return false;
}
}
return true;
}
int str2abs(const std::string& name)
{
return evdev_abs_names[name];
@ -694,6 +707,10 @@ int str2key(const std::string& name)
{
return evdev_key_names[name];
}
else if (is_number_(name))
{
return boost::lexical_cast<int>(name);
}
else
{
throw std::runtime_error("str2key: couldn't convert string: '" + name + "'");

View file

@ -101,8 +101,8 @@ FirestormDualController::FirestormDualController(struct usb_device* dev_, bool i
if (err != 0)
{
std::ostringstream out;
out << "Error couldn't claim the USB interface: " << strerror(-err) << std::endl
<< "Try to run 'rmmod xpad' and start xboxdrv again.";
out << "Error couldn't claim the USB interface: " << usb_strerror() << std::endl
<< "Try to run 'rmmod xpad' and then xboxdrv again or start xboxdrv with the option --detach-kernel-driver.";
throw std::runtime_error(out.str());
}
}

View file

@ -25,6 +25,7 @@
#include "helper.hpp"
#include "saitek_p2500_controller.hpp"
#include "usb_helper.hpp"
struct SaitekP2500Msg
{
@ -58,7 +59,7 @@ struct SaitekP2500Msg
} __attribute__((__packed__));
SaitekP2500Controller::SaitekP2500Controller(struct usb_device* dev_) :
SaitekP2500Controller::SaitekP2500Controller(struct usb_device* dev_, bool try_detach) :
dev(dev_),
handle(),
left_rumble(-1),
@ -71,15 +72,12 @@ SaitekP2500Controller::SaitekP2500Controller(struct usb_device* dev_) :
}
else
{
// FIXME: Do not always do that unrequested
usb_detach_kernel_driver_np(handle, 0);
int err = usb_claim_interface(handle, 0);
int err = usb_claim_n_detach_interface(handle, 0, try_detach);
if (err != 0)
{
std::ostringstream out;
out << "Error couldn't claim the USB interface: " << strerror(-err) << std::endl
<< "Try to run 'rmmod xpad' and start xboxdrv again.";
<< "Try to run 'rmmod xpad' and then xboxdrv again or start xboxdrv with the option --detach-kernel-driver.";
throw std::runtime_error(out.str());
}
}

View file

@ -33,7 +33,7 @@ private:
int right_rumble;
public:
SaitekP2500Controller(struct usb_device* dev);
SaitekP2500Controller(struct usb_device* dev, bool try_detach);
~SaitekP2500Controller();
void set_rumble(uint8_t left, uint8_t right);

View file

@ -56,7 +56,7 @@ Xbox360Controller::Xbox360Controller(struct usb_device* dev_, bool is_guitar_, b
{
std::ostringstream out;
out << "Error set USB configuration: " << usb_strerror() << std::endl
<< "Try to run 'rmmod xpad' and start xboxdrv again.";
<< "Try to run 'rmmod xpad' and then xboxdrv again or start xboxdrv with the option --detach-kernel-driver.";
throw std::runtime_error(out.str());
}
}
@ -73,7 +73,7 @@ Xbox360Controller::Xbox360Controller(struct usb_device* dev_, bool is_guitar_, b
{
std::ostringstream out;
out << " Error couldn't claim the USB interface: " << usb_strerror() << std::endl
<< "Try to run 'rmmod xpad' and start xboxdrv again.";
<< "Try to run 'rmmod xpad' and then xboxdrv again or start xboxdrv with the option --detach-kernel-driver.";
throw std::runtime_error(out.str());
}
}

View file

@ -25,13 +25,14 @@
#include <boost/format.hpp>
#include <stdexcept>
#include "usb_read_thread.hpp"
#include "helper.hpp"
#include "xboxmsg.hpp"
#include "usb_helper.hpp"
#include "usb_read_thread.hpp"
#include "xbox360_wireless_controller.hpp"
#include "xboxmsg.hpp"
Xbox360WirelessController::Xbox360WirelessController(struct usb_device* dev_,
int controller_id) :
Xbox360WirelessController::Xbox360WirelessController(struct usb_device* dev_, int controller_id,
bool try_detach) :
dev(dev_),
handle(),
endpoint(),
@ -54,12 +55,12 @@ Xbox360WirelessController::Xbox360WirelessController(struct usb_device* dev_,
}
else
{
int err = usb_claim_interface(handle, interface);
int err = usb_claim_n_detach_interface(handle, interface, try_detach);
if (err != 0)
{
std::ostringstream out;
out << "Error couldn't claim the USB interface: " << strerror(-err) << std::endl
<< "Try to run 'rmmod xpad' and start xboxdrv again.";
<< "Try to run 'rmmod xpad' and then xboxdrv again or start xboxdrv with the option --detach-kernel-driver.";
throw std::runtime_error(out.str());
}
}

View file

@ -22,6 +22,7 @@
#include "xbox_generic_controller.hpp"
class USBReadThread;
class XboxGenericMsg;
struct XPadDevice;
/** */
@ -39,8 +40,7 @@ private:
std::auto_ptr<USBReadThread> read_thread;
public:
Xbox360WirelessController(struct usb_device* dev,
int controller_id);
Xbox360WirelessController(struct usb_device* dev, int controller_id, bool try_detach);
virtual ~Xbox360WirelessController();
void set_rumble(uint8_t left, uint8_t right);

View file

@ -22,10 +22,11 @@
#include <stdexcept>
#include <string.h>
#include "usb_helper.hpp"
#include "xboxmsg.hpp"
#include "xbox_controller.hpp"
XboxController::XboxController(struct usb_device* dev_) :
XboxController::XboxController(struct usb_device* dev_, bool try_detach) :
dev(dev_),
handle(),
endpoint_in(1),
@ -40,12 +41,12 @@ XboxController::XboxController(struct usb_device* dev_) :
else
{
// FIXME: bInterfaceNumber shouldn't be hardcoded
int err = usb_claim_interface(handle, 0);
int err = usb_claim_n_detach_interface(handle, 0, try_detach);
if (err != 0)
{
std::ostringstream out;
out << "Error couldn't claim the USB interface: " << strerror(-err) << std::endl
<< "Try to run 'rmmod xpad' and start xboxdrv again.";
<< "Try to run 'rmmod xpad' and then xboxdrv again or start xboxdrv with the option --detach-kernel-driver.";
throw std::runtime_error(out.str());
}
}

View file

@ -37,7 +37,7 @@ private:
void find_endpoints();
public:
XboxController(struct usb_device* dev);
XboxController(struct usb_device* dev, bool try_detach);
virtual ~XboxController();
void set_rumble(uint8_t left, uint8_t right);

View file

@ -21,6 +21,8 @@
#include <stdint.h>
class XboxGenericMsg;
class XboxGenericController
{
private:

View file

@ -500,7 +500,7 @@ Xboxdrv::run_main(const CommandLineOptions& opts)
{
case GAMEPAD_XBOX:
case GAMEPAD_XBOX_MAT:
controller = std::auto_ptr<XboxGenericController>(new XboxController(dev));
controller = std::auto_ptr<XboxGenericController>(new XboxController(dev, opts.detach_kernel_driver));
break;
case GAMEPAD_XBOX360_GUITAR:
@ -512,7 +512,7 @@ Xboxdrv::run_main(const CommandLineOptions& opts)
break;
case GAMEPAD_XBOX360_WIRELESS:
controller = std::auto_ptr<XboxGenericController>(new Xbox360WirelessController(dev, opts.wireless_id));
controller = std::auto_ptr<XboxGenericController>(new Xbox360WirelessController(dev, opts.wireless_id, opts.detach_kernel_driver));
break;
case GAMEPAD_FIRESTORM:
@ -524,7 +524,7 @@ Xboxdrv::run_main(const CommandLineOptions& opts)
break;
case GAMEPAD_SAITEK_P2500:
controller = std::auto_ptr<XboxGenericController>(new SaitekP2500Controller(dev));
controller = std::auto_ptr<XboxGenericController>(new SaitekP2500Controller(dev, opts.detach_kernel_driver));
break;
default: