diff -Nru xboxdrv-0.8.4/NEWS xboxdrv-0.8.5/NEWS --- xboxdrv-0.8.4/NEWS 2012-01-24 10:57:24.000000000 +0000 +++ xboxdrv-0.8.5/NEWS 2013-04-07 17:27:49.000000000 +0000 @@ -1,3 +1,25 @@ +xboxdrv 0.8.5 - (07/Apr/2013) +============================= + +* fixed errors on shutdown related to libusbx +* updated button mapping for --mimic-xpad-wireless and --mimic-xpad +* workaround for evdev values that don't fall into the given min/max +* added some support for Playstation 3 LED and rumble +* added support for Batarang Xbox 360 controller +* added support for Elite Glow +* added support for Hori Real Arcade Pro VX-SA +* added support for Hori SOULCALIBUR V Stick +* added support for Hori XBOX 360 EX 2 with Turbo +* added support for Logic3 Controller +* added support for Logitech F310 +* added support for Logitech F510 +* added support for Logitech F710 +* added support for Razer Onza Tournament Edition +* added support for Street Fighter IV FightStick TE +* added support for Thrustmaster, Inc. GPX Controller +* added support for Xbox Airflo wired controller + + xboxdrv 0.8.4 - (24/Jan/2012) ============================= diff -Nru xboxdrv-0.8.4/PROTOCOL xboxdrv-0.8.5/PROTOCOL --- xboxdrv-0.8.4/PROTOCOL 2012-01-24 10:57:24.000000000 +0000 +++ xboxdrv-0.8.5/PROTOCOL 2013-04-07 17:27:49.000000000 +0000 @@ -395,6 +395,31 @@ +--------- seems the same as in Event Data LED: { 0x00, 0x00, 0x08, 0x40 + (mode % 0x0e), 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } +To turn device 1 off, send: { 00 00 08 C0 00 00 00 00 00 00 00 00 } to endpoint 1 +To enable wireless controller chatpad events, send: 00 00 0C 1B 00 00 00 00 00 00 00 00 +You will have to send alternating 1E/1F keep-alive packets (every second or so, I guess) to keep the chatpad events flowing: + +send 1 00 00 0C 1B 00 00 00 00 00 00 00 00 +send 1 00 00 08 C0 00 00 00 00 00 00 00 00 +send 1 00 00 0C 1F 00 00 00 00 00 00 00 00 +send 1 00 00 0C 1E 00 00 00 00 00 00 00 00 +send 1 00 00 0C 0c 00 00 00 00 00 00 00 00 +send 1 00 00 0C 17 00 00 00 00 00 00 00 00 + +00 00 0C 8 00 00 00 00 00 00 00 00 capslock +00 00 0C 9 00 00 00 00 00 00 00 00 square +00 00 0C a 00 00 00 00 00 00 00 00 circle +00 00 0C b 00 00 00 00 00 00 00 00 people +00 00 0C c 00 00 00 00 00 00 00 00 backlight +00 00 0C 11 00 00 00 00 00 00 00 00 capslock +00 00 0C 12 00 00 00 00 00 00 00 00 square +00 00 0C 13 00 00 00 00 00 00 00 00 square and capslock +00 00 0C 14 00 00 00 00 00 00 00 00 circle +00 00 0C 15 00 00 00 00 00 00 00 00 capslock and circle +00 00 0C 16 00 00 00 00 00 00 00 00 circle, square +00 00 0C 17 00 00 00 00 00 00 00 00 circle, square, capslock +00 00 0C 1b 00 00 00 00 00 00 00 00 makes backlight led go on on keypress + Wireless Headset LED: ??? // Start (LED Status Messages) diff -Nru xboxdrv-0.8.4/SConstruct xboxdrv-0.8.5/SConstruct --- xboxdrv-0.8.4/SConstruct 2012-01-24 10:57:24.000000000 +0000 +++ xboxdrv-0.8.5/SConstruct 2013-04-07 17:27:49.000000000 +0000 @@ -1,5 +1,6 @@ # -*- python -*- - + +import os import subprocess import string import re @@ -67,7 +68,7 @@ fout.write("/* EOF */\n") -env = Environment(BUILDERS = { +env = Environment(ENV=os.environ, BUILDERS = { 'DBusGlue' : Builder(action = build_dbus_glue), 'Bin2H' : Builder(action = build_bin2h) }) diff -Nru xboxdrv-0.8.4/VERSION xboxdrv-0.8.5/VERSION --- xboxdrv-0.8.4/VERSION 2012-01-24 10:57:24.000000000 +0000 +++ xboxdrv-0.8.5/VERSION 2013-04-07 17:27:49.000000000 +0000 @@ -1 +1 @@ -0.8.4 \ No newline at end of file +0.8.5 \ No newline at end of file diff -Nru xboxdrv-0.8.4/debian/changelog xboxdrv-0.8.5/debian/changelog --- xboxdrv-0.8.4/debian/changelog 2013-03-13 07:08:28.000000000 +0000 +++ xboxdrv-0.8.5/debian/changelog 2013-05-05 10:18:08.000000000 +0000 @@ -1,8 +1,17 @@ -xboxdrv (0.8.4-1build1) raring; urgency=low +xboxdrv (0.8.5-1) unstable; urgency=low - * No-change rebuild against libudev1 + * New upstream version + * debian/control: + - bump Standards-Version to 3.9.4 (no change needed) + * debian/patches/: + - drop use-PATH.patch (not needed anymore as the whole environment is + imported now) + * debian/control: + - use canonical anonscm.d.o URLs in the Vcs-* fields + * debian/copyright: + - update the copyright years - -- Martin Pitt Wed, 13 Mar 2013 07:08:28 +0000 + -- Andrey Rahmatullin Sun, 05 May 2013 16:17:43 +0600 xboxdrv (0.8.4-1) unstable; urgency=low diff -Nru xboxdrv-0.8.4/debian/control xboxdrv-0.8.5/debian/control --- xboxdrv-0.8.4/debian/control 2012-06-22 09:25:19.000000000 +0000 +++ xboxdrv-0.8.5/debian/control 2013-05-05 10:18:08.000000000 +0000 @@ -5,10 +5,10 @@ Uploaders: Andrey Rahmatullin Build-Depends: debhelper (>= 9), scons, libusb-1.0-0-dev, libx11-dev, libboost-dev, libdbus-glib-1-dev, libudev-dev -Standards-Version: 3.9.3 +Standards-Version: 3.9.4 Homepage: http://pingus.seul.org/~grumbel/xboxdrv/ -Vcs-Git: git://git.debian.org/pkg-games/xboxdrv.git -Vcs-Browser: http://git.debian.org/?p=pkg-games/xboxdrv.git;a=summary +Vcs-Git: git://anonscm.debian.org/pkg-games/xboxdrv.git +Vcs-Browser: http://anonscm.debian.org/gitweb/?p=pkg-games/xboxdrv.git;a=summary Package: xboxdrv Architecture: linux-any diff -Nru xboxdrv-0.8.4/debian/copyright xboxdrv-0.8.5/debian/copyright --- xboxdrv-0.8.4/debian/copyright 2012-06-22 09:25:19.000000000 +0000 +++ xboxdrv-0.8.5/debian/copyright 2013-05-05 10:18:08.000000000 +0000 @@ -4,12 +4,12 @@ Source: http://pingus.seul.org/~grumbel/xboxdrv/ Files: * -Copyright: 2008-2011, Ingo Ruhnke +Copyright: 2008-2013, Ingo Ruhnke License: GPL-3+ Files: debian/* Copyright: 2009-2010, Ingo Ruhnke - 2011-2012, Andrey Rahmatullin + 2011-2013, Andrey Rahmatullin License: GPL-3+ Files: tools/evtest.c tools/jstest.c diff -Nru xboxdrv-0.8.4/debian/patches/series xboxdrv-0.8.5/debian/patches/series --- xboxdrv-0.8.4/debian/patches/series 2012-06-22 09:25:19.000000000 +0000 +++ xboxdrv-0.8.5/debian/patches/series 2013-05-05 10:18:08.000000000 +0000 @@ -1,2 +1 @@ fix-xboxdrv-manpage.patch -use-PATH.patch diff -Nru xboxdrv-0.8.4/debian/patches/use-PATH.patch xboxdrv-0.8.5/debian/patches/use-PATH.patch --- xboxdrv-0.8.4/debian/patches/use-PATH.patch 2012-06-22 09:25:19.000000000 +0000 +++ xboxdrv-0.8.5/debian/patches/use-PATH.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,31 +0,0 @@ -Description: Use $PATH from the environment in scons - scons clears the environment by default which means ccache is not used during - the package build. -Author: Andrey Rahmatullin -Forwarded: no -Last-Update: 2012-06-16 - -diff --git a/SConstruct b/SConstruct -index 71e95cf..e244302 100644 ---- a/SConstruct -+++ b/SConstruct -@@ -1,5 +1,6 @@ - # -*- python -*- - -+import os - import subprocess - import string - import re -@@ -70,7 +71,11 @@ def build_bin2h(target, source, env): - env = Environment(BUILDERS = { - 'DBusGlue' : Builder(action = build_dbus_glue), - 'Bin2H' : Builder(action = build_bin2h) -- }) -+ }, -+ ENV = { -+ 'PATH' : os.environ['PATH'], -+ }, -+ ) - - opts = Variables(['custom.py'], ARGUMENTS) - diff -Nru xboxdrv-0.8.4/examples/multi-controller.sh xboxdrv-0.8.5/examples/multi-controller.sh --- xboxdrv-0.8.4/examples/multi-controller.sh 1970-01-01 00:00:00.000000000 +0000 +++ xboxdrv-0.8.5/examples/multi-controller.sh 2013-04-07 17:27:49.000000000 +0000 @@ -0,0 +1,39 @@ +#!/bin/bash + +# Bash script for using two (or more) wireless controllers +# ######################################################## +# +# Running xboxdrv regularly only supports a single controller, using +# two or more controllers is however possible by launching multiple +# instances of xbdroxv. When launching two instances the build-in +# command execution of xboxdrv no longer can be used, so keeping track +# and killing the xboxdrv processes has to be done manually. + +# tell bash to exit the script when something goes wrong +set -e + +# launch xboxdrv for the first wireless controller +xboxdrv \ + --wid 0 \ + --deadzone 6000 --trigger-as-button -s --dpad-as-button \ + --ui-buttonmap back=KEY_ESC,start=KEY_ENTER,dd=KEY_DOWN,du=KEY_UP,dr=KEY_RIGHT,dl=KEY_LEFT & +XBOXPID1=$! + +# launch xboxdrv for the second wireless controller +xboxdrv \ + --wid 1 \ + --deadzone 6000 --trigger-as-button -s --dpad-as-button \ + --ui-buttonmap back=KEY_ESC,start=KEY_ENTER,dd=KEY_DOWN,du=KEY_UP,dr=KEY_RIGHT,dl=KEY_LEFT & +XBOXPID2=$! + +# launch your game +/usr/games/you_game + +# after the game has exited, kill the started xboxdrv processes and +# wait for them to shut down +kill $XBOXPID1 +kill $XBOXPID2 +wait $XBOXPID1 +wait $XBOXPID2 + +# EOF # diff -Nru xboxdrv-0.8.4/src/evdev_controller.cpp xboxdrv-0.8.5/src/evdev_controller.cpp --- xboxdrv-0.8.4/src/evdev_controller.cpp 2012-01-24 10:57:24.000000000 +0000 +++ xboxdrv-0.8.5/src/evdev_controller.cpp 2013-04-07 17:27:49.000000000 +0000 @@ -25,6 +25,7 @@ #include #include "evdev_helper.hpp" +#include "helper.hpp" #include "log.hpp" #define BITS_PER_LONG (sizeof(long) * 8) @@ -214,7 +215,11 @@ case EV_ABS: { const struct input_absinfo& absinfo = m_absinfo[ev.code]; - m_absmap.process(msg_inout, ev.code, ev.value, absinfo.minimum, absinfo.maximum); + m_absmap.process(msg_inout, ev.code, + // some buggy USB devices report values + // outside the given range, so we clamp it + Math::clamp(absinfo.minimum, ev.value, absinfo.maximum), + absinfo.minimum, absinfo.maximum); return true; // FIXME: wrong break; } diff -Nru xboxdrv-0.8.4/src/firestorm_dual_controller.cpp xboxdrv-0.8.5/src/firestorm_dual_controller.cpp --- xboxdrv-0.8.4/src/firestorm_dual_controller.cpp 2012-01-24 10:57:24.000000000 +0000 +++ xboxdrv-0.8.5/src/firestorm_dual_controller.cpp 2013-04-07 17:27:49.000000000 +0000 @@ -99,8 +99,6 @@ FirestormDualController::~FirestormDualController() { - usb_cancel_read(); - usb_release_interface(0); } void diff -Nru xboxdrv-0.8.4/src/generic_usb_controller.cpp xboxdrv-0.8.5/src/generic_usb_controller.cpp --- xboxdrv-0.8.4/src/generic_usb_controller.cpp 2012-01-24 10:57:24.000000000 +0000 +++ xboxdrv-0.8.5/src/generic_usb_controller.cpp 2013-04-07 17:27:49.000000000 +0000 @@ -62,8 +62,6 @@ GenericUSBController::~GenericUSBController() { - usb_cancel_read(); - usb_release_interface(m_interface); } void diff -Nru xboxdrv-0.8.4/src/playstation3_usb_controller.cpp xboxdrv-0.8.5/src/playstation3_usb_controller.cpp --- xboxdrv-0.8.4/src/playstation3_usb_controller.cpp 2012-01-24 10:57:24.000000000 +0000 +++ xboxdrv-0.8.5/src/playstation3_usb_controller.cpp 2013-04-07 17:27:49.000000000 +0000 @@ -37,20 +37,94 @@ Playstation3USBController::~Playstation3USBController() { - usb_cancel_read(); - usb_release_interface(0); } +#define HID_GET_REPORT 0x01 +#define HID_GET_IDLE 0x02 +#define HID_GET_PROTOCOL 0x03 +#define HID_SET_REPORT 0x09 +#define HID_SET_IDLE 0x0A +#define HID_SET_PROTOCOL 0x0B + +#define HID_REPORT_TYPE_INPUT 0x01 +#define HID_REPORT_TYPE_OUTPUT 0x02 +#define HID_REPORT_TYPE_FEATURE 0x03 + void Playstation3USBController::set_rumble_real(uint8_t left, uint8_t right) { - // not implemented + //log_tmp("Rumble: " << static_cast(left) << " " << static_cast(right)); + uint8_t cmd[] = { + // FIXME: 254 isn't quite right and the right motor seems to be on/off only + 0x00, 254, right, 254, left, // rumble values + 0x00, 0x00, 0x00, 0x00, 0x03, // 0x10=LED1 .. 0x02=LED4 + 0xff, 0x27, 0x10, 0x00, 0x32, // LED 4 + 0xff, 0x27, 0x10, 0x00, 0x32, // LED 3 + 0xff, 0x27, 0x10, 0x00, 0x32, // LED 2 + 0xff, 0x27, 0x10, 0x00, 0x32, // LED 1 + 0x00, 0x00, 0x00, 0x00, 0x00 + }; + + usb_control(LIBUSB_ENDPOINT_OUT | LIBUSB_REQUEST_TYPE_CLASS | LIBUSB_RECIPIENT_INTERFACE, // RequestType + HID_SET_REPORT, // Request + (HID_REPORT_TYPE_OUTPUT << 8) | 0x01, // Value + 0, // Index + cmd, sizeof(cmd)); } void Playstation3USBController::set_led_real(uint8_t status) { - // not implemented + //log_tmp("LEDset: " << static_cast(status)); + + // convert Xbox360 LED status value to PS3 + uint8_t ps3_status = 0; + switch(status) + { + case 1: + ps3_status = 0xf<<1; + break; + + case 2: + case 6: + ps3_status = 0x1<<1; + break; + + case 3: + case 7: + ps3_status = 0x1<<2; + break; + + case 4: + case 8: + ps3_status = 0x1<<3; + break; + + case 5: + case 9: + ps3_status = 0x1<<4; + break; + + default: + ps3_status = 0x0; + break; + } + + uint8_t cmd[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, // rumble values + 0x00, 0x00, 0x00, 0x00, ps3_status, // 0x10=LED1 .. 0x02=LED4 + 0xff, 0x27, 0x10, 0x00, 0x32, // LED 4 + 0xff, 0x27, 0x10, 0x00, 0x32, // LED 3 + 0xff, 0x27, 0x10, 0x00, 0x32, // LED 2 + 0xff, 0x27, 0x10, 0x00, 0x32, // LED 1 + 0x00, 0x00, 0x00, 0x00, 0x00 + }; + + usb_control(LIBUSB_ENDPOINT_OUT | LIBUSB_REQUEST_TYPE_CLASS | LIBUSB_RECIPIENT_INTERFACE, // RequestType + HID_SET_REPORT, // Request + (HID_REPORT_TYPE_OUTPUT << 8) | 0x01, // Value + 0, // Index + cmd, sizeof(cmd)); } #define bitswap(x) x = ((x & 0x00ff) << 8) | ((x & 0xff00) >> 8) diff -Nru xboxdrv-0.8.4/src/saitek_p2500_controller.cpp xboxdrv-0.8.5/src/saitek_p2500_controller.cpp --- xboxdrv-0.8.4/src/saitek_p2500_controller.cpp 2012-01-24 10:57:24.000000000 +0000 +++ xboxdrv-0.8.5/src/saitek_p2500_controller.cpp 2013-04-07 17:27:49.000000000 +0000 @@ -66,8 +66,6 @@ SaitekP2500Controller::~SaitekP2500Controller() { - usb_cancel_read(); - usb_release_interface(0); } void diff -Nru xboxdrv-0.8.4/src/uinput_options.cpp xboxdrv-0.8.5/src/uinput_options.cpp --- xboxdrv-0.8.4/src/uinput_options.cpp 2012-01-24 10:57:24.000000000 +0000 +++ xboxdrv-0.8.5/src/uinput_options.cpp 2013-04-07 17:27:49.000000000 +0000 @@ -61,7 +61,7 @@ get_btn_map().bind(XBOX_BTN_START, ButtonEvent::create_key(DEVICEID_JOYSTICK, BTN_START)); get_btn_map().bind(XBOX_BTN_GUIDE, ButtonEvent::create_key(DEVICEID_JOYSTICK, BTN_MODE)); - get_btn_map().bind(XBOX_BTN_BACK, ButtonEvent::create_key(DEVICEID_JOYSTICK, BTN_BACK)); + get_btn_map().bind(XBOX_BTN_BACK, ButtonEvent::create_key(DEVICEID_JOYSTICK, BTN_SELECT)); get_btn_map().bind(XBOX_BTN_A, ButtonEvent::create_key(DEVICEID_JOYSTICK, BTN_A)); get_btn_map().bind(XBOX_BTN_B, ButtonEvent::create_key(DEVICEID_JOYSTICK, BTN_B)); @@ -92,14 +92,14 @@ get_axis_map().clear(); get_btn_map().clear(); - get_btn_map().bind(XBOX_DPAD_UP, ButtonEvent::create_key(DEVICEID_JOYSTICK, BTN_0)); - get_btn_map().bind(XBOX_DPAD_DOWN, ButtonEvent::create_key(DEVICEID_JOYSTICK, BTN_1)); - get_btn_map().bind(XBOX_DPAD_LEFT, ButtonEvent::create_key(DEVICEID_JOYSTICK, BTN_LEFT)); - get_btn_map().bind(XBOX_DPAD_RIGHT, ButtonEvent::create_key(DEVICEID_JOYSTICK, BTN_RIGHT)); + get_btn_map().bind(XBOX_DPAD_UP, ButtonEvent::create_key(DEVICEID_JOYSTICK, BTN_TRIGGER_HAPPY3)); + get_btn_map().bind(XBOX_DPAD_DOWN, ButtonEvent::create_key(DEVICEID_JOYSTICK, BTN_TRIGGER_HAPPY4)); + get_btn_map().bind(XBOX_DPAD_LEFT, ButtonEvent::create_key(DEVICEID_JOYSTICK, BTN_TRIGGER_HAPPY1)); + get_btn_map().bind(XBOX_DPAD_RIGHT, ButtonEvent::create_key(DEVICEID_JOYSTICK, BTN_TRIGGER_HAPPY2)); get_btn_map().bind(XBOX_BTN_START, ButtonEvent::create_key(DEVICEID_JOYSTICK, BTN_START)); get_btn_map().bind(XBOX_BTN_GUIDE, ButtonEvent::create_key(DEVICEID_JOYSTICK, BTN_MODE)); - get_btn_map().bind(XBOX_BTN_BACK, ButtonEvent::create_key(DEVICEID_JOYSTICK, BTN_BACK)); + get_btn_map().bind(XBOX_BTN_BACK, ButtonEvent::create_key(DEVICEID_JOYSTICK, BTN_SELECT)); get_btn_map().bind(XBOX_BTN_A, ButtonEvent::create_key(DEVICEID_JOYSTICK, BTN_A)); get_btn_map().bind(XBOX_BTN_B, ButtonEvent::create_key(DEVICEID_JOYSTICK, BTN_B)); diff -Nru xboxdrv-0.8.4/src/usb_controller.cpp xboxdrv-0.8.5/src/usb_controller.cpp --- xboxdrv-0.8.4/src/usb_controller.cpp 2012-01-24 10:57:24.000000000 +0000 +++ xboxdrv-0.8.5/src/usb_controller.cpp 2013-04-07 17:27:49.000000000 +0000 @@ -28,7 +28,8 @@ USBController::USBController(libusb_device* dev) : m_dev(dev), m_handle(0), - m_read_transfer(), + m_transfers(), + m_interfaces(), m_usbpath(), m_usbid(), m_name() @@ -78,7 +79,29 @@ USBController::~USBController() { - //log_tmp("~USBController"); + // cancel all transfers + for(std::set::iterator it = m_transfers.begin(); it != m_transfers.end(); ++it) + { + libusb_cancel_transfer(*it); + } + + // wait for cancel to succeed + while (!m_transfers.empty()) + { + int ret = libusb_handle_events(NULL); + if (ret != 0) + { + log_error("libusb_handle_events() failure: " << ret); + } + } + + // release all claimed interfaces + for(std::set::iterator it = m_interfaces.begin(); it != m_interfaces.end(); ++it) + { + libusb_release_interface(m_handle, *it); + } + + // read and write transfers might still be going on and might need to be canceled libusb_close(m_handle); } @@ -103,23 +126,26 @@ void USBController::usb_submit_read(int endpoint, int len) { - assert(!m_read_transfer); - - m_read_transfer = libusb_alloc_transfer(0); + libusb_transfer* transfer = libusb_alloc_transfer(0); uint8_t* data = static_cast(malloc(sizeof(uint8_t) * len)); - m_read_transfer->flags |= LIBUSB_TRANSFER_FREE_BUFFER; - libusb_fill_interrupt_transfer(m_read_transfer, m_handle, + 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(m_read_transfer); + ret = libusb_submit_transfer(transfer); if (ret != LIBUSB_SUCCESS) { + libusb_free_transfer(transfer); raise_exception(std::runtime_error, "libusb_submit_transfer(): " << usb_strerror(ret)); } + else + { + m_transfers.insert(transfer); + } } void @@ -127,7 +153,6 @@ { libusb_transfer* transfer = libusb_alloc_transfer(0); transfer->flags |= LIBUSB_TRANSFER_FREE_BUFFER; - transfer->flags |= LIBUSB_TRANSFER_FREE_TRANSFER; // copy data into a newly allocated buffer uint8_t* data = static_cast(malloc(sizeof(uint8_t) * len)); @@ -143,8 +168,13 @@ ret = libusb_submit_transfer(transfer); if (ret != LIBUSB_SUCCESS) { + libusb_free_transfer(transfer); raise_exception(std::runtime_error, "libusb_submit_transfer(): " << usb_strerror(ret)); } + else + { + m_transfers.insert(transfer); + } } void @@ -154,7 +184,6 @@ { libusb_transfer* transfer = libusb_alloc_transfer(0); transfer->flags |= LIBUSB_TRANSFER_FREE_BUFFER; - transfer->flags |= LIBUSB_TRANSFER_FREE_TRANSFER; // create and fill control buffer uint8_t* data = static_cast(malloc(wLength + 8)); @@ -168,14 +197,22 @@ ret = libusb_submit_transfer(transfer); if (ret != LIBUSB_SUCCESS) { + libusb_free_transfer(transfer); raise_exception(std::runtime_error, "libusb_submit_transfer(): " << usb_strerror(ret)); } + else + { + m_transfers.insert(transfer); + } } void USBController::on_control(libusb_transfer* transfer) { log_debug("control transfer"); + + m_transfers.erase(transfer); + libusb_free_transfer(transfer); } void @@ -183,19 +220,12 @@ { if (transfer->status != LIBUSB_TRANSFER_COMPLETED) { - log_error("USB write failure: " << transfer->length << ": " << usb_transfer_strerror(transfer->status)); + if (transfer->status != LIBUSB_TRANSFER_CANCELLED) + log_error("USB write failure: " << transfer->length << ": " << usb_transfer_strerror(transfer->status)); } -} -void -USBController::usb_cancel_read() -{ - if (m_read_transfer) - { - libusb_cancel_transfer(m_read_transfer); - libusb_free_transfer(m_read_transfer); - m_read_transfer = 0; - } + m_transfers.erase(transfer); + libusb_free_transfer(transfer); } void @@ -203,31 +233,30 @@ { assert(transfer); - // FIXME: check for LIBUSB_TRANSFER_COMPLETED - - // process data - XboxGenericMsg msg; - if (parse(transfer->buffer, transfer->actual_length, &msg)) + if (transfer->status != LIBUSB_TRANSFER_COMPLETED) { - submit_msg(msg); - } + if (transfer->status != LIBUSB_TRANSFER_CANCELLED) + log_error("USB read failure: " << transfer->length << ": " << usb_transfer_strerror(transfer->status)); - if (false) // cleanup - { + m_transfers.erase(transfer); libusb_free_transfer(transfer); } - else // resubmit - { + else + { + // process data + XboxGenericMsg msg; + if (parse(transfer->buffer, transfer->actual_length, &msg)) + { + submit_msg(msg); + } + int ret; ret = libusb_submit_transfer(transfer); if (ret != LIBUSB_SUCCESS) // could also check for LIBUSB_ERROR_NO_DEVICE { log_error("failed to resubmit USB transfer: " << usb_strerror(ret)); - assert(m_read_transfer == transfer); - libusb_free_transfer(transfer); - m_read_transfer = 0; send_disconnect(); } @@ -237,6 +266,11 @@ void USBController::usb_claim_interface(int ifnum, bool try_detach) { + // keep track of all claimed interfaces so they can be released in + // the destructor + assert(m_interfaces.find(ifnum) == m_interfaces.end()); + m_interfaces.insert(ifnum); + int err = usb_claim_n_detach_interface(m_handle, ifnum, try_detach); if (err != 0) { @@ -247,13 +281,6 @@ } } -void -USBController::usb_release_interface(int ifnum) -{ - // should be called before closing the device handle - libusb_release_interface(m_handle, ifnum); -} - int USBController::usb_find_ep(int direction, uint8_t if_class, uint8_t if_subclass, uint8_t if_protocol) { diff -Nru xboxdrv-0.8.4/src/usb_controller.hpp xboxdrv-0.8.5/src/usb_controller.hpp --- xboxdrv-0.8.4/src/usb_controller.hpp 2012-01-24 10:57:24.000000000 +0000 +++ xboxdrv-0.8.5/src/usb_controller.hpp 2013-04-07 17:27:49.000000000 +0000 @@ -22,6 +22,7 @@ #include #include #include +#include #include "controller.hpp" @@ -31,7 +32,8 @@ libusb_device* m_dev; libusb_device_handle* m_handle; - libusb_transfer* m_read_transfer; + std::set m_transfers; + std::set m_interfaces; std::string m_usbpath; std::string m_usbid; @@ -50,10 +52,8 @@ int usb_find_ep(int direction, uint8_t if_class, uint8_t if_subclass, uint8_t if_protocol); void usb_claim_interface(int ifnum, bool try_detach); - void usb_release_interface(int ifnum); void usb_submit_read(int endpoint, int len); - void usb_cancel_read(); void usb_write(int endpoint, uint8_t* data, int len); void usb_control(uint8_t bmRequestType, uint8_t bRequest, diff -Nru xboxdrv-0.8.4/src/xbox360_controller.cpp xboxdrv-0.8.5/src/xbox360_controller.cpp --- xboxdrv-0.8.4/src/xbox360_controller.cpp 2012-01-24 10:57:24.000000000 +0000 +++ xboxdrv-0.8.5/src/xbox360_controller.cpp 2013-04-07 17:27:49.000000000 +0000 @@ -86,8 +86,6 @@ Xbox360Controller::~Xbox360Controller() { - usb_cancel_read(); - usb_release_interface(0); } void diff -Nru xboxdrv-0.8.4/src/xbox360_wireless_controller.cpp xboxdrv-0.8.5/src/xbox360_wireless_controller.cpp --- xboxdrv-0.8.4/src/xbox360_wireless_controller.cpp 2012-01-24 10:57:24.000000000 +0000 +++ xboxdrv-0.8.5/src/xbox360_wireless_controller.cpp 2013-04-07 17:27:49.000000000 +0000 @@ -50,8 +50,6 @@ Xbox360WirelessController::~Xbox360WirelessController() { - usb_cancel_read(); - usb_release_interface(m_interface); } void @@ -68,7 +66,7 @@ { // +--- Why not just status? // v - uint8_t ledcmd[] = { 0x00, 0x00, 0x08, 0x40 + (status % 0x0e), 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + uint8_t ledcmd[] = { 0x00, 0x00, 0x08, static_cast(0x40 + (status % 0x0e)), 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; usb_write(m_endpoint, ledcmd, sizeof(ledcmd)); } diff -Nru xboxdrv-0.8.4/src/xbox_controller.cpp xboxdrv-0.8.5/src/xbox_controller.cpp --- xboxdrv-0.8.4/src/xbox_controller.cpp 2012-01-24 10:57:24.000000000 +0000 +++ xboxdrv-0.8.5/src/xbox_controller.cpp 2013-04-07 17:27:49.000000000 +0000 @@ -41,8 +41,6 @@ XboxController::~XboxController() { - usb_cancel_read(); - usb_release_interface(0); } void diff -Nru xboxdrv-0.8.4/src/xboxdrv_daemon.cpp xboxdrv-0.8.5/src/xboxdrv_daemon.cpp --- xboxdrv-0.8.4/src/xboxdrv_daemon.cpp 2012-01-24 10:57:24.000000000 +0000 +++ xboxdrv-0.8.5/src/xboxdrv_daemon.cpp 2013-04-07 17:27:49.000000000 +0000 @@ -107,7 +107,10 @@ assert(!s_current); s_current = this; +#if !GLIB_CHECK_VERSION(2,35,0) g_type_init(); +#endif + m_gmain = g_main_loop_new(NULL, false); signal(SIGINT, &XboxdrvDaemon::on_sigint); diff -Nru xboxdrv-0.8.4/src/xpad_device.cpp xboxdrv-0.8.5/src/xpad_device.cpp --- xboxdrv-0.8.4/src/xpad_device.cpp 2012-01-24 10:57:24.000000000 +0000 +++ xboxdrv-0.8.5/src/xpad_device.cpp 2013-04-07 17:27:49.000000000 +0000 @@ -68,26 +68,39 @@ { GAMEPAD_XBOX360, 0x0f0d, 0x000a, "Hori Co. DOA4 FightStick" }, { GAMEPAD_XBOX360, 0x0f0d, 0x000d, "Hori Fighting Stick Ex2" }, { GAMEPAD_XBOX360, 0x0f0d, 0x0016, "Hori Real Arcade Pro Ex" }, + { GAMEPAD_XBOX360, 0x24c6, 0x5501, "Hori Real Arcade Pro VX-SA" }, + { GAMEPAD_XBOX360, 0x24c6, 0x5303, "Xbox Airflo wired controller" }, { GAMEPAD_XBOX360, 0x162e, 0xbeef, "Joytech Neo-Se Take2" }, + { GAMEPAD_XBOX360, 0x046d, 0xc21d, "Logitech F310" }, + { GAMEPAD_XBOX360, 0x046d, 0xc21e, "Logitech F510" }, + { GAMEPAD_XBOX360, 0x046d, 0xc21f, "Logitech F710" }, { GAMEPAD_XBOX360, 0x046d, 0xc242, "Logitech ChillStream" }, { GAMEPAD_XBOX360, 0x0738, 0xcb03, "Saitek P3200 Rumble Pad - PC/Xbox 360" }, { GAMEPAD_XBOX360, 0x0738, 0xcb02, "Saitek Cyborg Rumble Pad - PC/Xbox 360" }, { GAMEPAD_XBOX360, 0x0e6f, 0x0201, "Pelican TSZ360 Pad" }, { GAMEPAD_XBOX360, 0x0e6f, 0x0213, "Afterglow Gamepad for Xbox 360" }, + { GAMEPAD_XBOX360, 0x0e6f, 0x0401, "Logic3 Controller" }, { GAMEPAD_XBOX360, 0x12ab, 0x0301, "PDP AFTERGLOW AX.1" }, { GAMEPAD_XBOX360_GUITAR, 0x1430, 0x4748, "RedOctane Guitar Hero X-plorer" }, { GAMEPAD_XBOX360_GUITAR, 0x1bad, 0x0002, "Harmonix Guitar for Xbox 360" }, { GAMEPAD_XBOX360_GUITAR, 0x1bad, 0x0003, "Harmonix Drum Kit for Xbox 360" }, { GAMEPAD_XBOX360, 0x1bad, 0xf016, "Mad Catz Xbox 360 Controller" }, { GAMEPAD_XBOX360, 0x1bad, 0xf028, "Street Fighter IV FightPad" }, + { GAMEPAD_XBOX360, 0x1bad, 0xf038, "Street Fighter IV FightStick TE" }, { GAMEPAD_XBOX360, 0x1bad, 0xf901, "Gamestop Xbox 360 Controller" }, { GAMEPAD_XBOX360, 0x1bad, 0xf903, "Tron Xbox 360 controller" }, { GAMEPAD_XBOX360, 0x15e4, 0x3f00, "Power A Mini Pro Elite" }, + { GAMEPAD_XBOX360, 0x15e4, 0x3f10, "Batarang Xbox 360 controller" }, { GAMEPAD_XBOX360_WIRELESS, 0x045e, 0x0291, "Microsoft Xbox 360 Wireless Controller" }, // RF Module from the Xbox360 { GAMEPAD_XBOX360_WIRELESS, 0x045e, 0x0719, "Microsoft Xbox 360 Wireless Controller (PC)" }, // official Wireless Receiver { GAMEPAD_XBOX360, 0x1689, 0xfd00, "Razer Onza" }, + { GAMEPAD_XBOX360, 0x1689, 0xfd01, "Razer Onza Tournament Edition" }, { GAMEPAD_XBOX360, 0x12ab, 0x0004, "DDR Universe 2 Mat" }, { GAMEPAD_XBOX360, 0x15e4, 0x3f0a, "Xbox Airflo wired controller" }, + { GAMEPAD_XBOX360, 0x24c6, 0x5300, "Power A Mini Pro Elite Glow" }, + { GAMEPAD_XBOX360, 0x24c6, 0x5500, "Hori XBOX 360 EX 2 with Turbo" }, + { GAMEPAD_XBOX360, 0x24c6, 0x5506, "Hori SOULCALIBUR V Stick" }, + { GAMEPAD_XBOX360, 0x24c6, 0x5b02, "Thrustmaster, Inc. GPX Controller" }, { GAMEPAD_XBOX_MAT, 0x0738, 0x4540, "Mad Catz Beat Pad" }, { GAMEPAD_XBOX_MAT, 0x0738, 0x6040, "Mad Catz Beat Pad Pro" },