Skip to content

xbox 360 controller chatpad support#367

Open
az4521 wants to merge 7 commits into
paroj:masterfrom
az4521:chatpad-support
Open

xbox 360 controller chatpad support#367
az4521 wants to merge 7 commits into
paroj:masterfrom
az4521:chatpad-support

Conversation

@az4521

@az4521 az4521 commented Jun 23, 2026

Copy link
Copy Markdown

full disclosure this was basically entirely ai-generated

i tested it on bazzite with kernel 7.0.9, works great. a few of the keys on the chatpad aren't mapped (the accent ones, euro/gbp/microsoft points symbols, anything not on an ANSI keyboard basically)

#242

az4521 and others added 7 commits June 18, 2026 19:34
Add support for the Xbox 360 Chatpad keyboard accessory on both wired and
wireless controllers. The Chatpad is exposed as a separate keyboard input
device that reports standard key events.

On wired controllers (045e:028e) the Chatpad lives on a dedicated vendor
specific interface, which the driver claims; it runs the enable handshake
over the control endpoint, listens for [0x00][mod][key1][key2] reports on
the interface's interrupt-IN endpoint, and keeps the Chatpad awake with
alternating 0x1f/0x1e keep-alive control transfers.

On wireless controllers the key reports are interleaved into the receiver's
data stream (00 02 00 f0 packets, payload at offset 24); the enable and
keep-alive commands are sent on the command OUT endpoint and the keyboard
device is created and destroyed together with the controller.

The green/orange/shift/people modifiers are reported as Alt/AltGr/Shift/Meta
so they can be remapped from userspace. Support can be disabled with the new
chatpad module parameter. Protocol details were taken from the xboxdrv
project.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Previously the green and orange chatpad keys were reported as Alt/AltGr
modifiers, which produced nothing useful since no keymap knows the chatpad
layout. Treat them instead as symbol layers: holding green or orange and
pressing a key emits the keycode for the symbol printed on that keycap, with
Shift synthesized for shifted symbols (e.g. green Q -> '!', green D -> '{').

Key state is now reconciled against what was actually emitted, so the right
keycode is released even if the layer changed while a key was held. Symbols
with no Linux keycode (the accented letters and a few others on the
international chatpad) are ignored. Shift stays Shift and people stays Meta.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Route the chatpad modifier-LED commands through the wireless command OUT
endpoint (00 00 0c <value>) for XTYPE_XBOX360W, mirroring the wired control
transfer which uses the same command byte. Extend the LED trigger, teardown
and suspend/resume handling to cover the wireless transport.

No public source documents wireless chatpad LED control; the command format
is inferred from the wired one, so this is experimental and may do nothing on
hardware. Wired behaviour is unchanged.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Wireless modifier-LED control is confirmed working on hardware, so state it
plainly in the README and code comments instead of hedging. No functional
change.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Orange+Shift is the orange "CAPS" legend on the chatpad's shift key. On the
rising edge of that modifier combination, emit a KEY_CAPSLOCK tap so userspace
toggles Caps Lock.

Register the chatpad input device as an LED consumer (EV_LED/LED_CAPSL) so the
input core reports the real system caps-lock state to it (set by libinput or
the console, on any keyboard). The shift backlight then doubles as a caps-lock
indicator: lit while shift is held or while Caps Lock is on. Works on both
wired and wireless transports.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Collapse the chatpad LED helpers: the command value is index/0x08|index for
the shift/green/orange/people order, so the 4-case switch and the four
per-modifier if-blocks become a small bit table plus a loop.

Fold the four Shift/Meta assert/release blocks in the key handler into a
single hold() helper. All events in a report land in one input_sync frame and
a key-up emits no character, so reconciling both modifiers before the keys is
equivalent to the previous before/after split. No functional change.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The wired (control transfer) vs wireless (00 00 0c <cmd> packet) dispatch was
duplicated in both the LED and keep-alive code. Factor it into a single
xpad_chatpad_send_cmd() helper, reflecting that both transports carry the same
chatpad command bytes. No functional change.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant