All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/2] hw/usb/dev-hid: Apple Magic Keyboard and Mighty Mouse emulators
@ 2026-07-19 15:23 Matthew Jackson
  2026-07-19 15:23 ` [PATCH 1/2] hw/usb/dev-hid: add apple-magic-keyboard Matthew Jackson
  2026-07-19 15:23 ` [PATCH 2/2] hw/usb/dev-hid: add apple-mighty-mouse Matthew Jackson
  0 siblings, 2 replies; 6+ messages in thread
From: Matthew Jackson @ 2026-07-19 15:23 UTC (permalink / raw)
  To: qemu-devel; +Cc: kraxel

This series adds two new self-contained USB HID devices to
hw/usb/dev-hid.c: apple-magic-keyboard and apple-mighty-mouse,
emulating the USB-cable face of the real Apple Magic Keyboard with
Numeric Keypad (PID 0x026c) and Apple Mighty Mouse (PID 0x0304).

Why this exists
---------------

QEMU has no USB-HID device that macOS recognises as a real Apple
peripheral. With usb-kbd / usb-tablet, macOS guests:

  * Run Keyboard Setup Assistant on first boot - costs 3-5 minutes
    on interactive installs and effectively hangs headless
    (VNC / SPICE) installs.

  * Bind the generic IOUSBHostHIDDevice driver instead of the Apple
    HID driver chain (AppleUSBTopCaseHIDDriver,
    AppleDeviceManagementHIDEventService,
    AppleHIDKeyboardEventDriverV2, AppleHIDMouseEventDriver). Several
    recovery / install / multi-touch UI panels behave correctly only
    when the chain matches an Apple-VID peripheral.

The new devices ship the real wire format (descriptors, HID report
descriptors, endpoint topology) byte-identical to real hardware in
USB-cable mode. The keyboard's boot-interface report descriptor is
byte-for-byte the real Apple Magic Keyboard with Numeric Keypad
descriptor (182 bytes, four application collections), captured from
a real keyboard plugged into a Mac via the macOS IOReg dump.

Self-contained, additive only
-----------------------------

Zero existing files are modified outside the new device blocks in
hw/usb/dev-hid.c. The existing usb-kbd / usb-mouse / usb-tablet
devices and their vmstate are unchanged. Migration of existing VMs
is unaffected.

Apple-vendor identity
---------------------

Both devices declare idVendor 0x05ac (Apple) and the real PIDs.
Precedent: isa-applesmc ships the verbatim Apple OSK string; mac99
emulates real Apple PowerPC hardware; apple-gfx.m (Phil Dennis-Jordan,
2024) emulates Apple's host paravirt GPU. The Apple PnP IDs are
public identifiers (linux-usb's usb.ids database) and emulating them
does not bypass any Apple licensing check beyond what isa-applesmc
already requires.

If reviewers prefer the Apple PID/VID gated behind an
apple-id=on/off device property (default off), a v2 patch is prepared
addressing that. The v1 carries the Apple IDs unconditionally,
matching the precedent set by sibling devices.

Why Mighty Mouse, not Magic Trackpad
------------------------------------

An earlier draft of this series shipped apple-magic-tablet emulating
Apple Magic Trackpad 2 (PID 0x0265). Magic Trackpad 2 binds
AppleMultitouchTrackpadHIDEventDriver in macOS, which gates cursor on
a 1387-byte vendor-multitouch frame format we do not have ground-truth
wire bytes for. Guessing the wire layout produced AppleHIDStack hangs
during recovery boots that wasted multiple debug cycles.

Apple Mighty Mouse (PID 0x0304) is Apple's wired ball mouse, M9087,
released 2005. It binds the generic AppleHIDMouseEventDriver /
IOHIDPointing chain natively — handles standard 5-byte boot mouse
reports (3-bit button mask + signed int8 dX/dY + signed int8 vWheel +
signed int8 hWheel) without any vendor-specific protocol. Same
"Apple-VID-or-fail" property the Apple HID stack checks for; cursor +
click + scroll all work unconditionally. v1 of this series ships this
device.

For backward compatibility with downstream consumers using the earlier
draft's name (which exists in some out-of-tree downstream forks),
patch 0002 also registers a TypeInfo legacy alias `apple-magic-tablet`
inheriting from the canonical `apple-mighty-mouse` type — both
`-device` strings resolve to the same implementation. The alias has
no permanent place in upstream and can be dropped any time after
in-tree consumers move to the canonical name.

Tested
------

Tested on macOS 15.7.5 against a stock retail installer, mos-docker
test rig (privileged container, network_mode=host, --device /dev/kvm,
QEMU 11.0.0 patched binary).

  * Phase 2 regression (patched QEMU + macOS HD + isa-applesmc + ICH9
    globals + generic usb-kbd / usb-tablet) — boot to login PASS,
    visual gold-image diff well under 2% threshold.

  * Phase 3 regression (+ apple-magic-keyboard + apple-mighty-mouse
    swap) — boot to login PASS, visual gold-image diff well under 2%
    threshold. macOS' AppleUSBTopCaseHIDDriver +
    AppleHIDKeyboardEventDriverV2 bind on the keyboard;
    AppleHIDMouseEventDriver / IOHIDPointing binds on the mouse.

  * HID delivery verified via a second screendump after driving a
    deterministic input sequence (QMP send-key for 'a','b','c' →
    three password dots in the loginwindow field; QMP
    input-send-event with absolute pointer to centre coords → cursor
    visible at centre). Gold-image diff against
    phase-3-input-gold.png passes — proves keyboard and mouse
    delivery, not just enumeration.

  * Linux-guest descriptor walk (xHCI + libusb) — descriptors and HID
    report descriptors decode cleanly. PID/VID/strings as expected.

  * Visible keystroke proof — QMP send-key Return advances macOS
    recovery's language-picker UI; cursor moves on QMP
    input-send-event abs-pointer.

  * Migration smoke test — VM saves + restores without device
    breakage on both new types.

Per-patch summary
-----------------

  0001 — apple-magic-keyboard: composite USB device, two HID
    interfaces. Interface 0 carries the Apple-vendor descriptor (182
    bytes, byte-for-byte real device) with vendor reports 0xe0 / 0x9a
    / 0x90 the Apple driver chain probes. Interface 1 carries the
    Magic Keyboard boot-keyboard descriptor (boot kbd Report 0x01 +
    Consumer Eject + Vendor 0xff Usage 0x03; consumer multimedia
    Report 0x52; system control feature Report 0x09; vendor Report
    0x3f 64-byte feature blob). Wired to the QEMU input subsystem via
    qemu_input_handler_register(). STALLs on GET_REPORT for undeclared
    report IDs (matches real-device USB HID behaviour — returning
    zero-fill there causes macOS' HID parser to wedge during
    IOHIDInterface::start). SET_REPORT sets actual_length so the host
    doesn't retry indefinitely.

  0002 — apple-mighty-mouse: single HID interface, single IN endpoint,
    standard boot mouse + scroll Report Descriptor (5-byte report —
    3-bit button mask + dX + dY + vWheel + hWheel). Wired to QEMU's
    input subsystem accepting REL motion + ABS motion + BTN events.
    ABS events (from VNC) are converted to REL via a last_abs_x/y
    delta tracker. Bounded queue (depth 64) drains accumulated motion
    across multiple reports per input sync so cursor movement stays
    responsive under large pointer deltas. Includes the
    `apple-magic-tablet` legacy TypeInfo alias as described above.

Series root
-----------

Generated against qemu.git v11.0.0. Each patch applies cleanly and
`make check` is green on x86_64.

  git fetch origin master
  git checkout -b apple-magic-hid origin/master
  git am 0001-*.patch
  git am 0002-*.patch

Matthew Jackson (2):
  hw/usb/dev-hid: add apple-magic-keyboard
  hw/usb/dev-hid: add apple-mighty-mouse

 hw/usb/dev-hid.c | 1411 ++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 1411 insertions(+)

--
2.50.1 (Apple Git-155)


^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2026-07-20 18:25 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-19 15:23 [PATCH 0/2] hw/usb/dev-hid: Apple Magic Keyboard and Mighty Mouse emulators Matthew Jackson
2026-07-19 15:23 ` [PATCH 1/2] hw/usb/dev-hid: add apple-magic-keyboard Matthew Jackson
2026-07-19 15:23 ` [PATCH 2/2] hw/usb/dev-hid: add apple-mighty-mouse Matthew Jackson
2026-07-20  8:22   ` Peter Maydell
2026-07-20 16:51     ` Matthew Jackson
2026-07-20 18:24       ` Peter Maydell

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.