-
Notifications
You must be signed in to change notification settings - Fork 5
libtrueforce
A native Linux C implementation of the Logitech TrueForce SDK
(trueforce_sdk_x64.dll, version 1.3.11), living at
userspace/libtrueforce/. It lets native Linux applications drive TrueForce
directly, no Wine involved: telemetry-driven haptic generators, custom test
rigs, non-Steam game engines. Its first in-repo consumer is logi-tf-sim
(Simulated TrueForce Internals).
It is not required for the Proton recipe: SDK games use Logitech's own signed DLLs through Wine (see Force Feedback in Games).
- Talks to the wheel's interface-2 hidraw node directly, implementing the wire protocol documented in TrueForce Protocol: discovery, session bring-up (the 68-packet two-pass init), KF (constant-force) torque, TF (audio-haptic) streaming, gain, damping, pause/resume, and the version and capability getters. All verified end to end against a live RS50.
- Supports the RS50 (
046d:c276) and G Pro (046d:c272/046d:c268); the two wheels use byte-for-byte identical packets. - KF calls route through evdev on the same physical wheel; TF samples stream to the hidraw node at 1 kHz.
include/trueforce.h mirrors the 62 named exports of the Windows SDK so
a Linux app (or a Wine PE shim) can call the same API with minimal
translation; Windows-isms (HANDLE, GUID, wide strings) are translated to
plain C. Return codes are zero on success, negative errno-like on failure
(LOGITF_ERR_INVALID_ARG, _NOT_FOUND, _NOT_SUPPORTED, _IO, _BUSY).
The groups:
| Group | Representative calls |
|---|---|
| Module lifecycle |
dllOpen(), dllClose(), COM no-ops DllRegisterServer() / DllUnregisterServer()
|
| Discovery |
logiTrueForceAvailable(index), logiTrueForceSupported(index), DirectInput-flavored variants |
| Session |
logiWheelOpenByDirectInputA/W(), logiWheelClose(), logiWheelSdkHasControl()
|
| Versioning |
logiWheelGetCoreLibraryVersion(), logiWheelGetVersion()
|
| Operating range |
logiWheelGet/SetOperatingRangeDegrees/Radians(), bounds getters, force mode |
| RPM / LEDs |
logiWheelGetRpmLedCaps(), logiWheelSetRpmLeds(), logiWheelPlayLeds(rpm, first, redline)
|
| Angle |
logiTrueForceGetAngleDegrees/Radians(), angular velocity |
| Kinetic force (KF) |
logiTrueForceSetTorqueKF(nm), piecewise variant, clear, gain, max torque getters, reconstruction filter |
| TrueForce stream (TF) |
logiTrueForceSetTorqueTF{double,float,int8,int16,int32}(), logiTrueForceSetStreamTF(), clear, gain, rate bounds |
| Damping |
logiTrueForceSet/GetDamping(), GetDampingMax()
|
| Haptic thread |
logiTrueForceGetHapticRate(), thread status |
| Pause / sync | logiTrueForcePause/Resume/IsPaused/Sync() |
Streaming semantics: all SetTorqueTF* / SetStreamTF calls feed a
4096-entry internal ring drained by a dedicated thread at the wheel's 1 kHz
sample rate. If the ring fills, the calls block until space is available
(up to ~4 s at full saturation); treat them as synchronous.
One API has no Windows counterpart: logitf_get_stream_feedback() exposes
the wheel's type-0x02 responses collected while a stream is active (real-time
wheel position on the same path and cadence as the stream, a device-side
sample counter, and the still-undecoded motor/status fields). Useful for
closed-loop haptics and for measuring the wheel's consumption rate.
cd userspace/libtrueforce
make # builds libtrueforce.so.1.3.11 and tests
sudo make install # library + header under PREFIX (default /usr/local)
sudo make udev-install # the hidraw access ruleLink with -ltrueforce and include <trueforce.h>. A static
libtrueforce.a is also built (this is what logi-tf-sim links).
The udev rule (udev/99-logitech-trueforce.rules) grants read/write on the
interface-2 hidraw node of the supported wheels to the input group and
tags it uaccess for logind sessions. Replug the wheel after installing it.
Verify discovery:
./tests/discover
# libtrueforce 1.3.11
# [0] available: supported=yes, paused=nolibtrueforce is LGPL-2.1-or-later, while the rest of the repository is GPL-2.0-only. The intent: any application, including proprietary ones, may link libtrueforce (statically or dynamically) and drive TrueForce, but changes to the library itself must stay open. This is what lets the library serve as a general TrueForce ingest API for the Linux ecosystem, the same role the SDK DLL plays on Windows.
These are strong direct-drive wheels (RS50 up to 8 Nm, G PRO up to 11 Nm).
The wheel may rotate when the kernel driver loads, on replug, on profile
switch, and when the TrueForce init sequence first runs after library load
(the first SetTorqueKF/SetTorqueTF* call in a session). Keep hands clear
or firmly hold the rim at those moments. The library's test programs expect
you to already be holding the wheel.