Skip to content

Commit

Permalink
Merge pull request #4054 from Be-ing/hidapi_hidraw
Browse files Browse the repository at this point in the history
use hidraw backend of hidapi instead of libusb backend
  • Loading branch information
Holzhaus authored Jul 7, 2021
2 parents 84fa081 + f17c8bf commit b7f31ae
Show file tree
Hide file tree
Showing 7 changed files with 76 additions and 63 deletions.
39 changes: 1 addition & 38 deletions .github/workflows/build-checks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,44 +17,7 @@ jobs:
- name: Check out repository
uses: actions/checkout@v2
- name: Install build dependencies
run: |
sudo apt-get update && sudo apt-get install -y --no-install-recommends \
libavformat-dev \
libchromaprint-dev \
libebur128-dev \
libfftw3-dev \
libflac-dev \
libid3tag0-dev \
liblilv-dev \
libmad0-dev \
libmodplug-dev \
libmp3lame-dev \
libopus-dev \
libopusfile-dev \
libportmidi-dev \
libprotobuf-dev \
libqt5opengl5-dev \
libqt5sql5-sqlite \
libqt5svg5-dev \
libqt5x11extras5-dev \
librubberband-dev \
libshout-idjc-dev \
libsndfile1-dev \
libsoundtouch-dev \
libsqlite3-dev \
libtag1-dev \
libupower-glib-dev \
libusb-1.0-0-dev \
libwavpack-dev \
portaudio19-dev \
protobuf-compiler \
qt5-default \
qtdeclarative5-dev \
qtscript5-dev \
qt5keychain-dev \
clazy \
clang-tidy \
cmake
run: tools/debian_buildenv.sh setup
- name: Create build directory
run: mkdir build
- name: Configure (clazy)
Expand Down
25 changes: 19 additions & 6 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2694,21 +2694,34 @@ if(HID)
find_library(AppKit_LIBRARY AppKit REQUIRED)
target_link_libraries(mixxx-hidapi PUBLIC ${AppKit_LIBRARY})
elseif(UNIX)
if(NOT LibUSB_FOUND)
message(FATAL_ERROR "USB HID controller support on Unix with statically linked libhidapi-libusb requires libusb 1.0 and its development headers.")
if(CMAKE_SYSTEM_NAME STREQUAL Linux)
find_library(libudev_LIBRARY udev REQUIRED)
target_sources(mixxx-hidapi PRIVATE lib/hidapi/linux/hid.c)
target_link_libraries(mixxx-hidapi PRIVATE ${libudev_LIBRARY})
else()
if(NOT LibUSB_FOUND)
message(FATAL_ERROR "USB HID controller support on Unix with statically linked libhidapi-libusb requires libusb 1.0 and its development headers.")
endif()
target_sources(mixxx-hidapi PRIVATE lib/hidapi/libusb/hid.c)
target_link_libraries(mixxx-hidapi PRIVATE LibUSB::LibUSB)
endif()
target_sources(mixxx-hidapi PRIVATE lib/hidapi/libusb/hid.c)
target_link_libraries(mixxx-hidapi PRIVATE LibUSB::LibUSB)
else()
message(FATAL_ERROR "USB HID controller support only possible on Windows/Mac OS/Linux/BSD.")
endif()
target_link_libraries(mixxx-lib PRIVATE mixxx-hidapi)
else()
message(STATUS "Linking libhidapi dynamically")
if(NOT HIDAPI_FOUND)
message(FATAL_ERROR "USB HID controller support requires libhidapi-libusb and its development headers.")
message(FATAL_ERROR "USB HID controller support requires hidapi and its development headers.")
endif()
# hidapi has two backends on Linux, one using the kernel's hidraw API and one using libusb.
# libusb obviously does not support Bluetooth HID devices, so use the hidraw backend. The
# libusb backend is the default, so hidraw needs to be selected explicitly at link time.
if(CMAKE_SYSTEM_NAME STREQUAL Linux)
target_link_libraries(mixxx-lib PRIVATE hidapi::hidraw)
else()
target_link_libraries(mixxx-lib PRIVATE hidapi::hidapi)
endif()
target_link_libraries(mixxx-lib PRIVATE hidapi::hidapi)
endif()
target_sources(mixxx-lib PRIVATE
src/controllers/hid/hidcontroller.cpp
Expand Down
18 changes: 18 additions & 0 deletions cmake/modules/Findhidapi.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,15 @@ find_library(hidapi_LIBRARY
)
mark_as_advanced(hidapi_LIBRARY)

if(CMAKE_SYSTEM_NAME STREQUAL Linux)
find_library(hidapi-hidraw_LIBRARY
NAMES hidapi-hidraw
PATHS ${PC_hidapi_LIBRARY_DIRS}
DOC "hidap-hidraw library"
)
mark_as_advanced(hidapi-hidraw_LIBRARY)
endif()

include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(
hidapi
Expand Down Expand Up @@ -98,5 +107,14 @@ if(hidapi_FOUND)
INTERFACE_COMPILE_OPTIONS "${PC_hidapi_CFLAGS_OTHER}"
INTERFACE_INCLUDE_DIRECTORIES "${hidapi_INCLUDE_DIR}"
)
if(CMAKE_SYSTEM_NAME STREQUAL Linux)
add_library(hidapi::hidraw UNKNOWN IMPORTED)
set_target_properties(hidapi::hidraw
PROPERTIES
IMPORTED_LOCATION "${hidapi-hidraw_LIBRARY}"
INTERFACE_COMPILE_OPTIONS "${PC_hidapi_CFLAGS_OTHER}"
INTERFACE_INCLUDE_DIRECTORIES "${hidapi_INCLUDE_DIR}"
)
endif()
endif()
endif()
34 changes: 19 additions & 15 deletions res/linux/mixxx-usb-uaccess.rules
Original file line number Diff line number Diff line change
Expand Up @@ -13,42 +13,46 @@
# Install and execute before 70-uaccess.rules, e.g. .../udev/rules.d/69-mixxx-usb-uaccess.rules

# Allen + Heath Ltd.
SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", ATTRS{idVendor}=="22f0", TAG+="uaccess"
KERNEL=="hidraw*", ATTRS{idVendor}=="22f0", TAG+="uaccess"
# Allen + Heath Xone 23C hardware mixer with USB audio interface
# This is required so all 4 input and all 4 output channels of the audio interface are available.
ACTION=="add", SUBSYSTEM=="usb", ATTR{idVendor}=="22f0", ATTR{idProduct}=="0008", ATTR{bConfigurationValue}="2"
# Arturia
SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", ATTRS{idVendor}=="1c75", TAG+="uaccess"
KERNEL=="hidraw*", ATTRS{idVendor}=="1c75", TAG+="uaccess"
# BEHRINGER International GmbH
SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", ATTRS{idVendor}=="1397", TAG+="uaccess"
KERNEL=="hidraw*", ATTRS{idVendor}=="1397", TAG+="uaccess"
# D&M Holdings, Inc. (Denon/Marantz)
SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", ATTRS{idVendor}=="154e", TAG+="uaccess"
KERNEL=="hidraw*", ATTRS{idVendor}=="154e", TAG+="uaccess"
# EKS (Otus)
SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", ATTRS{idVendor}=="1157", TAG+="uaccess"
KERNEL=="hidraw*", ATTRS{idVendor}=="1157", TAG+="uaccess"
# Gemini
SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", ATTRS{idVendor}=="23c7", TAG+="uaccess"
KERNEL=="hidraw*", ATTRS{idVendor}=="23c7", TAG+="uaccess"
# Guillemot Corp. (Hercules)
KERNEL=="hidraw*", ATTRS{idVendor}=="06f8", TAG+="uaccess"
# Some older Hercules controllers are accessed through USB Bulk endpoints through libusb
SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", ATTRS{idVendor}=="06f8", TAG+="uaccess"
# inMusic (Numark, Denon)
SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", ATTRS{idVendor}=="15e4", TAG+="uaccess"
KERNEL=="hidraw*", ATTRS{idVendor}=="15e4", TAG+="uaccess"
# KORG, Inc.
SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", ATTRS{idVendor}=="0944", TAG+="uaccess"
KERNEL=="hidraw*", ATTRS{idVendor}=="0944", TAG+="uaccess"
# Native Instruments
KERNEL=="hidraw*", ATTRS{idVendor}=="17cc", TAG+="uaccess"
# First generation Native Instruments controllers can be accessed through USB Bulk endpoints through libusb
SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", ATTRS{idVendor}=="17cc", TAG+="uaccess"
# Nintendo Co., Ltd
SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", ATTRS{idVendor}=="057e", TAG+="uaccess"
KERNEL=="hidraw*", ATTRS{idVendor}=="057e", TAG+="uaccess"
# Pioneer Corp.
SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", ATTRS{idVendor}=="08e4", TAG+="uaccess"
KERNEL=="hidraw*", ATTRS{idVendor}=="08e4", TAG+="uaccess"
# AlphaTheta Corp.
SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", ATTRS{idVendor}=="2b73", TAG+="uaccess"
KERNEL=="hidraw*", ATTRS{idVendor}=="2b73", TAG+="uaccess"
# Rane
SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", ATTRS{idVendor}=="13e5", TAG+="uaccess"
KERNEL=="hidraw*", ATTRS{idVendor}=="13e5", TAG+="uaccess"
# Reloop
SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", ATTRS{idVendor}=="200c", TAG+="uaccess"
KERNEL=="hidraw*", ATTRS{idVendor}=="200c", TAG+="uaccess"
# Roland Corp.
SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", ATTRS{idVendor}=="0582", TAG+="uaccess"
KERNEL=="hidraw*", ATTRS{idVendor}=="0582", TAG+="uaccess"
# Sony Corp.
SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", ATTRS{idVendor}=="054c", TAG+="uaccess"
KERNEL=="hidraw*", ATTRS{idVendor}=="054c", TAG+="uaccess"

# Missing:
# - American Musical Supply (AMS/Mixars)
Expand Down
2 changes: 2 additions & 0 deletions src/controllers/hid/hidcontroller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,8 @@ QList<int> HidController::getInputReport(unsigned int reportID) {
int bytesRead;

m_pPollData[m_pollingBufferIndex][0] = reportID;
// FIXME: implement upstream for hidraw backend on Linux
// https://github.com/libusb/hidapi/issues/259
bytesRead = hid_get_input_report(m_pHidDevice, m_pPollData[m_pollingBufferIndex], kBufferSize);

controllerDebug(bytesRead
Expand Down
18 changes: 14 additions & 4 deletions src/controllers/hid/hidenumerator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,23 +65,33 @@ HidEnumerator::~HidEnumerator() {
QList<Controller*> HidEnumerator::queryDevices() {
qInfo() << "Scanning USB HID devices";

QStringList enumeratedDevices;
hid_device_info* device_info_list = hid_enumerate(0x0, 0x0);
for (const auto* device_info = device_info_list;
device_info;
device_info = device_info->next) {
auto deviceInfo = mixxx::hid::DeviceInfo(*device_info);
// The hidraw backend of hidapi on Linux returns many duplicate hid_device_info's from hid_enumerate,
// so filter them out.
// https://github.com/libusb/hidapi/issues/298
if (enumeratedDevices.contains(deviceInfo.pathRaw())) {
qInfo() << "Duplicate HID device, excluding" << deviceInfo;
continue;
}
enumeratedDevices.append(QString(deviceInfo.pathRaw()));

if (!recognizeDevice(*device_info)) {
qInfo()
<< "Excluding USB HID device"
<< "Excluding HID device"
<< deviceInfo;
continue;
}
qInfo() << "Found USB HID device:"
qInfo() << "Found HID device:"
<< deviceInfo;

if (!deviceInfo.isValid()) {
qWarning() << "USB permissions problem or device error."
<< "Your account needs write access to USB HID controllers.";
qWarning() << "HID device permissions problem or device error."
<< "Your account needs write access to HID controllers.";
continue;
}

Expand Down
3 changes: 3 additions & 0 deletions tools/debian_buildenv.sh
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ case "$1" in
sudo apt-get install -y --no-install-recommends -- \
ccache \
cmake \
clazy \
clang-tidy \
debhelper \
devscripts \
docbook-to-man \
Expand Down Expand Up @@ -72,6 +74,7 @@ case "$1" in
libsqlite3-dev \
libssl-dev \
libtag1-dev \
libudev-dev \
libupower-glib-dev \
libusb-1.0-0-dev \
libwavpack-dev \
Expand Down

0 comments on commit b7f31ae

Please sign in to comment.