Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat/abs rel mouse #13

Merged
merged 11 commits into from
Dec 4, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ Note: You should connect the data usb port (left one) to the raspberry, and NOT
from zero_hid import Mouse
m = Mouse()
for i in range(5):
m.move_relative(10, 10)
m.move(10, 10)
```
- Control keyboard
```python
Expand All @@ -37,6 +37,9 @@ k = Keyboard()
k.type('Hello world!')
```

## Examples
see [examples](examples)

## Tests
| Raspberry Pi Model | Raspbian Version | Kernel Version |
|---------------------|-------------------|----------------|
Expand Down
5 changes: 5 additions & 0 deletions examples/absolute_mouse.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
from zero_hid import Mouse

m = Mouse(absolute=True)
m.move(50,50)
m.close()
4 changes: 1 addition & 3 deletions examples/mouse_example.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
from zero_hid import Mouse



m = Mouse()
for i in range(5):
m.move_relative(5,5)
m.move(5,5)
m.close()
2 changes: 1 addition & 1 deletion tests/mouse_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ def test_left_click():
def test_move():
with open(random_file(), 'ab+') as f:
m = Mouse(f)
m.move_relative(100, 100)
m.move(100, 100)
f.seek(0)
data = f.read()
f.close()
Expand Down
81 changes: 69 additions & 12 deletions usb_gadget/init_usb_gadget
Original file line number Diff line number Diff line change
Expand Up @@ -74,12 +74,12 @@ D=$(mktemp)
} >> "$D"
cp "$D" "${KEYBOARD_FUNCTIONS_DIR}/report_desc"

# Mouse
MOUSE_FUNCTIONS_DIR="functions/hid.mouse"
mkdir -p "$MOUSE_FUNCTIONS_DIR"
echo 0 > "${MOUSE_FUNCTIONS_DIR}/protocol"
echo 0 > "${MOUSE_FUNCTIONS_DIR}/subclass"
echo 7 > "${MOUSE_FUNCTIONS_DIR}/report_length"
# Mouse Relative
MOUSE_RELATIVE_FUNCTIONS_DIR="functions/hid.mouse_relative"
mkdir -p "$MOUSE_RELATIVE_FUNCTIONS_DIR"
echo 0 > "${MOUSE_RELATIVE_FUNCTIONS_DIR}/protocol"
echo 0 > "${MOUSE_RELATIVE_FUNCTIONS_DIR}/subclass"
echo 7 > "${MOUSE_RELATIVE_FUNCTIONS_DIR}/report_length"
# Write the report descriptor
D=$(mktemp)
{
Expand All @@ -95,15 +95,69 @@ echo -ne \\x25\\x01 # LOGICAL_MAXIMUM (1)
echo -ne \\x95\\x08 # REPORT_COUNT (8)
echo -ne \\x75\\x01 # REPORT_SIZE (1)
echo -ne \\x81\\x02 # INPUT (Data,Var,Abs)

# x,y relative coordinates
echo -ne \\x05\\x01 # USAGE_PAGE (Generic Desktop)
echo -ne \\x09\\x30 # USAGE (X)
echo -ne \\x09\\x31 # USAGE (Y)
echo -ne \\x15\\x81 # LOGICAL_MINIMUM (-127)
echo -ne \\x25\\x7f # LOGICAL_MAXIMUM (127)
echo -ne \\x15\\x81 # LOGICAL_MINIMUM (-127)
echo -ne \\x25\\x7f # LOGICAL_MAXIMUM (127)
echo -ne \\x75\\x08 # REPORT_SIZE (16)
echo -ne \\x95\\x02 # REPORT_COUNT (2)
echo -ne \\x81\\x06 # INPUT (Data,Var,Rel)

# vertical wheel
echo -ne \\x09\\x38 # USAGE (wheel)
echo -ne \\x15\\x81 # LOGICAL_MINIMUM (-127)
echo -ne \\x25\\x7F # LOGICAL_MAXIMUM (127)
echo -ne \\x75\\x08 # REPORT_SIZE (8)
echo -ne \\x95\\x01 # REPORT_COUNT (1)
echo -ne \\x81\\x06 # INPUT (Data,Var,Rel)
# horizontal wheel
echo -ne \\x05\\x0C # USAGE_PAGE (Consumer Devices)
echo -ne \\x0A\\x38\\x02 # USAGE (AC Pan)
echo -ne \\x15\\x81 # LOGICAL_MINIMUM (-127)
echo -ne \\x25\\x7F # LOGICAL_MAXIMUM (127)
echo -ne \\x75\\x08 # REPORT_SIZE (8)
echo -ne \\x95\\x01 # REPORT_COUNT (1)
echo -ne \\x81\\x06 # INPUT (Data,Var,Rel)
echo -ne \\xC0 # END_COLLECTION
} >> "$D"
cp "$D" "${MOUSE_RELATIVE_FUNCTIONS_DIR}/report_desc"

# Mouse Absolute
MOUSE_ABSOLUTE_FUNCTIONS_DIR="functions/hid.mouse_absolute"
mkdir -p "$MOUSE_ABSOLUTE_FUNCTIONS_DIR"
echo 0 > "${MOUSE_ABSOLUTE_FUNCTIONS_DIR}/protocol"
echo 0 > "${MOUSE_ABSOLUTE_FUNCTIONS_DIR}/subclass"
echo 7 > "${MOUSE_ABSOLUTE_FUNCTIONS_DIR}/report_length"
# Write the report descriptor
D=$(mktemp)
{
echo -ne \\x05\\x01 # USAGE_PAGE (Generic Desktop)
echo -ne \\x09\\x02 # USAGE (Mouse)
echo -ne \\xA1\\x01 # COLLECTION (Application)
# 8-buttons
echo -ne \\x05\\x09 # USAGE_PAGE (Button)
echo -ne \\x19\\x01 # USAGE_MINIMUM (Button 1)
echo -ne \\x29\\x08 # USAGE_MAXIMUM (Button 8)
echo -ne \\x15\\x00 # LOGICAL_MINIMUM (0)
echo -ne \\x25\\x01 # LOGICAL_MAXIMUM (1)
echo -ne \\x95\\x08 # REPORT_COUNT (8)
echo -ne \\x75\\x01 # REPORT_SIZE (1)
echo -ne \\x81\\x02 # INPUT (Data,Var,Abs)


# x,y absolute coordinates
echo -ne \\x05\\x01 # USAGE_PAGE (Generic Desktop)
echo -ne \\x09\\x30 # USAGE (X)
echo -ne \\x09\\x31 # USAGE (Y)
echo -ne \\x15\\x00 # LOGICAL_MINIMUM (0)
echo -ne \\x26\\xff\\x7f # LOGICAL_MAXIMUM (65535)
echo -ne \\x75\\x10 # REPORT_SIZE (16)
echo -ne \\x95\\x02 # REPORT_COUNT (2)
echo -ne \\x81\\x02 # INPUT (Data,Var,RAbs)

# vertical wheel
echo -ne \\x09\\x38 # USAGE (wheel)
echo -ne \\x15\\x81 # LOGICAL_MINIMUM (-127)
Expand All @@ -121,7 +175,7 @@ echo -ne \\x95\\x01 # REPORT_COUNT (1)
echo -ne \\x81\\x06 # INPUT (Data,Var,Rel)
echo -ne \\xC0 # END_COLLECTION
} >> "$D"
cp "$D" "${MOUSE_FUNCTIONS_DIR}/report_desc"
cp "$D" "${MOUSE_ABSOLUTE_FUNCTIONS_DIR}/report_desc"

CONFIG_INDEX=1
CONFIGS_DIR="configs/c.${CONFIG_INDEX}"
Expand All @@ -133,8 +187,11 @@ mkdir -p "$CONFIGS_STRINGS_DIR"
echo "Config ${CONFIG_INDEX}: ECM network" > "${CONFIGS_STRINGS_DIR}/configuration"

ln -s "$KEYBOARD_FUNCTIONS_DIR" "${CONFIGS_DIR}/"
ln -s "$MOUSE_FUNCTIONS_DIR" "${CONFIGS_DIR}/"
ln -s "$MOUSE_RELATIVE_FUNCTIONS_DIR" "${CONFIGS_DIR}/"
ln -s "$MOUSE_ABSOLUTE_FUNCTIONS_DIR" "${CONFIGS_DIR}/"
ls /sys/class/udc > UDC

chmod 777 /dev/hidg0
chmod 777 /dev/hidg1
chmod 777 /dev/hidg0 # Keyboard
chmod 777 /dev/hidg1 # Mouse Relative
chmod 777 /dev/hidg2 # Mouse Absolute

3 changes: 2 additions & 1 deletion zero_hid/Keyboard.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

from .hid.keyboard import send_keystroke, release_keys
from .hid.keycodes import KeyCodes
from . import defaults
from time import sleep
import json
import operator
Expand All @@ -12,7 +13,7 @@

class Keyboard:

def __init__(self, dev='/dev/hidg0') -> None:
def __init__(self, dev=defaults.KEYBOARD_PATH) -> None:
if not hasattr(dev, 'write'): # check if file like object
self.dev = open(dev, 'ab+')
else:
Expand Down
33 changes: 21 additions & 12 deletions zero_hid/Mouse.py
Original file line number Diff line number Diff line change
@@ -1,38 +1,47 @@
from .hid.mouse import send_mouse_event
from . import defaults
from .hid.mouse import relative_mouse_event, absolute_mouse_event
from typing import SupportsInt


class RelativeMoveRangeError(Exception):
pass


class Mouse:
def __init__(self, dev='/dev/hidg1') -> None:
def __init__(self, dev = None, absolute = False) -> None:
if dev is None:
dev = defaults.ABSOLUTE_MOUSE_PATH if absolute else defaults.RELATIVE_MOUSE_PATH
self.move = self.__move_absolute if absolute else self.__move_relative # dynamic move method
self.__send_mouse_event = absolute_mouse_event if absolute else relative_mouse_event # dynamic mouse event method
if not hasattr(dev, 'write'): # check if file like object
self.dev = open(dev, 'ab+')
else:
self.dev = dev


def left_click(self):
send_mouse_event(self.dev, 0x1, 0, 0, 0, 0)
send_mouse_event(self.dev, 0x0, 0, 0, 0, 0)
self.__send_mouse_event(self.dev, 0x1, 0, 0, 0, 0)
self.__send_mouse_event(self.dev, 0x0, 0, 0, 0, 0)

def right_click(self):
send_mouse_event(self.dev, 0x1, 0, 0, 0, 0)
send_mouse_event(self.dev, 0x2, 0, 0, 0, 0)
def move_relative(self, x, y):
self.__send_mouse_event(self.dev, 0x2, 0, 0, 0, 0)
self.__send_mouse_event(self.dev, 0x0, 0, 0, 0, 0)

def __move_relative(self, x, y):
"""
move the mouse in relative mode
x,y should be in range of -127 to 127
"""
if not -127 <= x <= 127:
raise RelativeMoveRangeError(f"Value of x: {x} out of range (-127 - 127)")
if not -127 <= y <= 127:
RelativeMoveRangeError(f"Value of x: {y} out of range (-127 - 127)")
send_mouse_event(self.dev, 0x0, x, y, 0, 0)
RelativeMoveRangeError(f"Value of y: {y} out of range (-127 - 127)")
self.__send_mouse_event(self.dev, 0x0, x, y, 0, 0)

def __move_absolute(self, x, y):
if not 0 <= x <= 65535:
raise RelativeMoveRangeError(f"Value of x: {x} out of range (0 - 65535)")
if not 0 <= y <= 65535:
RelativeMoveRangeError(f"Value of y: {y} out of range (0 - 65535)")
self.__send_mouse_event(self.dev, 0x0, x, y, 0, 0)


def __enter__(self):
Expand Down
8 changes: 7 additions & 1 deletion zero_hid/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
from .Mouse import Mouse
from .Keyboard import Keyboard
from .hid.keycodes import KeyCodes
from . import defaults

__all__ = ['Mouse', 'Keyboard', 'KeyCodes']
__all__ = [
'Mouse',
'Keyboard',
'KeyCodes',
'defaults'
]
3 changes: 3 additions & 0 deletions zero_hid/defaults.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
KEYBOARD_PATH = '/dev/hidg0'
RELATIVE_MOUSE_PATH = '/dev/hidg1'
ABSOLUTE_MOUSE_PATH = '/dev/hidg2'
23 changes: 18 additions & 5 deletions zero_hid/hid/mouse.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,26 @@
from . import write as hid_write

def send_mouse_event(dev, buttons, relative_x, relative_y,
vertical_wheel_delta, horizontal_wheel_delta):
def relative_mouse_event(dev, buttons, x, y,
vertical_wheel_delta, horizontal_wheel_delta, absolute = False):
buf = [
buttons,
relative_x & 0xff,
relative_y & 0xff,
x & 0xff,
y & 0xff,
vertical_wheel_delta & 0xff,
horizontal_wheel_delta & 0xff
]
hid_write.write_to_hid_interface(dev, buf)



def absolute_mouse_event(dev, buttons, x, y,
vertical_wheel_delta, horizontal_wheel_delta):
buf = [
buttons,
x & 0xff,
(x >> 8) & 0xff, # Extract the upper byte of x
y & 0xff,
(y >> 8) & 0xff, # Extract the upper byte of y
vertical_wheel_delta & 0xff,
horizontal_wheel_delta & 0xff
]
hid_write.write_to_hid_interface(dev, buf)
Loading