-
Notifications
You must be signed in to change notification settings - Fork 0
Mouse Protocol Handlers
Pluggable protocol decoders that convert raw PS/2 mouse packet bytes into PointerEvent objects.
Mouse protocol handlers decode the varying byte sequences emitted by different PS/2 mouse types (standard 3-button, wheel mice, etc.) into a consistent PointerEvent representation. The MouseProtocolHandlerManager acts as a plugin-based factory, while individual handlers implement the MouseProtocolHandler interface to parse device-specific packets.
| Class | File | Responsibility |
|---|---|---|
MouseProtocolHandler |
core/src/driver/org/jnode/driver/input/MouseProtocolHandler.java |
Interface defining decode contract |
LogitechProtocol |
core/src/driver/org/jnode/driver/input/LogitechProtocol.java |
3-byte Logitech protocol implementation |
LogitechWheelMouseProtocol |
core/src/driver/org/jnode/driver/input/LogitechWheelMouseProtocol.java |
4-byte wheel mouse extension |
MouseProtocolHandlerManager |
core/src/driver/org/jnode/driver/input/MouseProtocolHandlerManager.java |
Plugin-based handler registry |
MouseInterpreter |
core/src/driver/org/jnode/driver/input/MouseInterpreter.java |
Probes mouse, selects handler, assembles packets |
PointerEvent |
core/src/driver/org/jnode/driver/input/PointerEvent.java |
The decoded event output |
InputPlugin |
core/src/driver/org/jnode/driver/input/InputPlugin.java |
Plugin entry point, binds manager to InitialNaming |
Handlers declare themselves via the org.jnode.driver.input.mouse-protocol-handlers extension point in their plugin descriptor:
<extension-point id="mouse-protocol-handlers"/>
<extension point="org.jnode.driver.input.mouse-protocol-handlers">
<handler name="Logitech Mouse" class="org.jnode.driver.input.LogitechProtocol"/>
<handler name="Logitech Wheel Mouse" class="org.jnode.driver.input.LogitechWheelMouseProtocol"/>
</extension>public interface MouseProtocolHandler {
String getName();
boolean supportsId(int id);
int getPacketSize();
PointerEvent buildEvent(byte[] data);
}Each handler reports:
- Whether it handles a given device ID (from
getPointerId()) - The packet size in bytes (3 for standard, 4 for wheel)
- The decoded event built from the raw bytes
MouseInterpreter.probe() performs device identification:
// Reset mouse to get base ID
d.initPointer(true);
pointerId = d.getPointerId();
// Attempt wheel mouse detection sequence
d.setRate(200);
d.setRate(100);
d.setRate(80);
pointerId = d.getPointerId(); // ID changes to 3 on wheel mice
// Select matching handler
for (MouseProtocolHandler p : mgr.protocolHandlers()) {
if (p.supportsId(pointerId)) {
this.protocol = p;
break;
}
}MouseInterpreter.handleScancode() accumulates bytes until a full packet is received, then delegates to the handler:
public synchronized PointerEvent handleScancode(int scancode) {
data[pos++] = (byte) (scancode & 0xff);
pos %= data.length;
if (pos != 0) {
return null; // Incomplete packet
}
return protocol.buildEvent(data);
}LogitechProtocol.buildEvent() decodes the 3-byte PS/2 mouse packet:
Byte 0: Y overflow, X overflow, Y sign, X sign, 1, Middle, Right, Left
Byte 1: X movement (signed, twos complement applied via sign bit)
Byte 2: Y movement (signed, twos complement applied via sign bit)
public PointerEvent buildEvent(byte[] data) {
final int d0 = data[0] & 0xFF;
final int d1 = data[1] & 0xFF;
final int d2 = data[2] & 0xFF;
// Discard packets with overflow indicators
if ((d0 & (0x40 | 0x80)) != 0)
return null;
final int buttons = d0 & 0x07;
final int x = (d1 != 0) ? d1 - ((d0 & 0x10) << 4) : 0;
final int y = (d2 != 0) ? ((d0 & 0x20) << 3) - d2 : 0;
return new PointerEvent(buttons, x, y, PointerEvent.RELATIVE);
}LogitechWheelMouseProtocol extends the base protocol with a 4th byte for wheel data:
public PointerEvent buildEvent(byte[] data) {
PointerEvent e = super.buildEvent(data);
if (e == null) return null;
int z = data[3];
if (z == 127) z = -1; // Center position maps to negative
return new PointerEvent(e.getButtons(), e.getX(), e.getY(), z, e.isAbsolute());
}The decoded event carries button state and X/Y/Z (wheel) values:
PointerEvent({LMR}) x y z REL
Button bits: BUTTON_LEFT=1, BUTTON_MIDDLE=4, BUTTON_RIGHT=2.
-
ID persistence anomaly: After wheel mouse detection,
pointerIdremains 3 on subsequent probes instead of resetting to 0. SeeMouseInterpreter.java:65TODO comment. - Overflow discard: Packets with X or Y overflow bits set are silently dropped — useful for detecting protocol mismatch.
-
Null returns:
buildEvent()returnsnullon invalid packets, whichMouseInterpreterpropagates asnull(no event delivered). -
Plugin initialization order:
MouseProtocolHandlerManagerrequires plugins to be started before handlers are registered via extension points.