kopia lustrzana https://github.com/micropython/micropython-lib
101 wiersze
3.3 KiB
Python
101 wiersze
3.3 KiB
Python
# MicroPython USB Mouse module
|
|
#
|
|
# MIT license; Copyright (c) 2023-2024 Angus Gratton
|
|
from micropython import const
|
|
import struct
|
|
import machine
|
|
|
|
from usb.device.hid import HIDInterface
|
|
|
|
_INTERFACE_PROTOCOL_MOUSE = const(0x02)
|
|
|
|
|
|
class MouseInterface(HIDInterface):
|
|
# A basic three button USB mouse HID interface
|
|
def __init__(self, interface_str="MicroPython Mouse"):
|
|
super().__init__(
|
|
_MOUSE_REPORT_DESC,
|
|
protocol=_INTERFACE_PROTOCOL_MOUSE,
|
|
interface_str=interface_str,
|
|
)
|
|
self._l = False # Left button
|
|
self._m = False # Middle button
|
|
self._r = False # Right button
|
|
self._buf = bytearray(3)
|
|
|
|
def send_report(self, dx=0, dy=0):
|
|
b = 0
|
|
if self._l:
|
|
b |= 1 << 0
|
|
if self._r:
|
|
b |= 1 << 1
|
|
if self._m:
|
|
b |= 1 << 2
|
|
|
|
# Wait for any pending report to be sent to the host
|
|
# before updating contents of _buf.
|
|
#
|
|
# This loop can be removed if you don't care about possibly missing a
|
|
# transient report, the final report buffer contents will always be the
|
|
# last one sent to the host (it just might lose one of the ones in the
|
|
# middle).
|
|
while self.busy():
|
|
machine.idle()
|
|
|
|
struct.pack_into("Bbb", self._buf, 0, b, dx, dy)
|
|
|
|
return super().send_report(self._buf)
|
|
|
|
def click_left(self, down=True):
|
|
self._l = down
|
|
return self.send_report()
|
|
|
|
def click_middle(self, down=True):
|
|
self._m = down
|
|
return self.send_report()
|
|
|
|
def click_right(self, down=True):
|
|
self._r = down
|
|
return self.send_report()
|
|
|
|
def move_by(self, dx, dy):
|
|
if not -127 <= dx <= 127:
|
|
raise ValueError("dx")
|
|
if not -127 <= dy <= 127:
|
|
raise ValueError("dy")
|
|
return self.send_report(dx, dy)
|
|
|
|
|
|
# Basic 3-button mouse HID Report Descriptor.
|
|
# This is based on Appendix E.10 of the HID v1.11 document.
|
|
# fmt: off
|
|
_MOUSE_REPORT_DESC = (
|
|
b'\x05\x01' # Usage Page (Generic Desktop)
|
|
b'\x09\x02' # Usage (Mouse)
|
|
b'\xA1\x01' # Collection (Application)
|
|
b'\x09\x01' # Usage (Pointer)
|
|
b'\xA1\x00' # Collection (Physical)
|
|
b'\x05\x09' # Usage Page (Buttons)
|
|
b'\x19\x01' # Usage Minimum (01),
|
|
b'\x29\x03' # Usage Maximun (03),
|
|
b'\x15\x00' # Logical Minimum (0),
|
|
b'\x25\x01' # Logical Maximum (1),
|
|
b'\x95\x03' # Report Count (3),
|
|
b'\x75\x01' # Report Size (1),
|
|
b'\x81\x02' # Input (Data, Variable, Absolute), ;3 button bits
|
|
b'\x95\x01' # Report Count (1),
|
|
b'\x75\x05' # Report Size (5),
|
|
b'\x81\x01' # Input (Constant), ;5 bit padding
|
|
b'\x05\x01' # Usage Page (Generic Desktop),
|
|
b'\x09\x30' # Usage (X),
|
|
b'\x09\x31' # Usage (Y),
|
|
b'\x15\x81' # Logical Minimum (-127),
|
|
b'\x25\x7F' # Logical Maximum (127),
|
|
b'\x75\x08' # Report Size (8),
|
|
b'\x95\x02' # Report Count (2),
|
|
b'\x81\x06' # Input (Data, Variable, Relative), ;2 position bytes (X & Y)
|
|
b'\xC0' # End Collection
|
|
b'\xC0' # End Collection
|
|
)
|
|
# fmt: on
|