66"""
77
88import array
9- import time
109import gc
11-
12- # pylint: disable=import-error
13- import usb .core
14-
10+ from adafruit_usb_host_mouse import find_and_init_boot_mouse
1511
1612# pylint: disable=invalid-name,no-member,too-many-instance-attributes,too-many-arguments
1713# pylint: disable=too-many-branches,too-many-statements,broad-except
@@ -34,182 +30,60 @@ def __init__(self, screen_width, screen_height, staff_y_start, staff_height):
3430 self .buf = None
3531 self .in_endpoint = None
3632
33+ self .sensitivity = 4 # Sensitivity factor for mouse movement
34+
3735 # Mouse position
38- self .mouse_x = screen_width // 2
39- self .mouse_y = screen_height // 2
36+ self .mouse_x = ( screen_width // 2 ) * self . sensitivity
37+ self .mouse_y = ( screen_height // 2 ) * self . sensitivity
4038
4139 def find_mouse (self ):
42- """Find the mouse device with multiple retry attempts"""
43- MAX_ATTEMPTS = 5
44- RETRY_DELAY = 1 # seconds
45-
46- for attempt in range (MAX_ATTEMPTS ):
47- try :
48- print (f"Mouse detection attempt { attempt + 1 } /{ MAX_ATTEMPTS } " )
49-
50- # Constants for USB control transfers
51- DIR_OUT = 0
52- # DIR_IN = 0x80 # Unused variable
53- REQTYPE_CLASS = 1 << 5
54- REQREC_INTERFACE = 1 << 0
55- HID_REQ_SET_PROTOCOL = 0x0B
56-
57- # Find all USB devices
58- devices_found = False
59- for device in usb .core .find (find_all = True ):
60- devices_found = True
61- print (f"Found device: { device .idVendor :04x} :{ device .idProduct :04x} " )
62-
63- try :
64- # Try to get device info
65- try :
66- manufacturer = device .manufacturer
67- product = device .product
68- except Exception : # pylint: disable=broad-except
69- manufacturer = "Unknown"
70- product = "Unknown"
71-
72- # Just use whatever device we find
73- self .mouse = device
74-
75- # Try to detach kernel driver
76- try :
77- has_kernel_driver = hasattr (device , 'is_kernel_driver_active' )
78- if has_kernel_driver and device .is_kernel_driver_active (0 ):
79- device .detach_kernel_driver (0 )
80- except Exception as e : # pylint: disable=broad-except
81- print (f"Error detaching kernel driver: { e } " )
82-
83- # Set configuration
84- try :
85- device .set_configuration ()
86- except Exception as e : # pylint: disable=broad-except
87- print (f"Error setting configuration: { e } " )
88- continue # Try next device
89-
90- # Just assume endpoint 0x81 (common for mice)
91- self .in_endpoint = 0x81
92- print (f"Using mouse: { manufacturer } , { product } " )
93-
94- # Set to report protocol mode
95- try :
96- bmRequestType = DIR_OUT | REQTYPE_CLASS | REQREC_INTERFACE
97- bRequest = HID_REQ_SET_PROTOCOL
98- wValue = 1 # 1 = report protocol
99- wIndex = 0 # First interface
100-
101- buf = bytearray (1 )
102- device .ctrl_transfer (bmRequestType , bRequest , wValue , wIndex , buf )
103- print ("Set to report protocol mode" )
104- except Exception as e : # pylint: disable=broad-except
105- print (f"Could not set protocol: { e } " )
106-
107- # Buffer for reading data
108- self .buf = array .array ("B" , [0 ] * 4 )
109- print ("Created 4-byte buffer for mouse data" )
110-
111- # Verify mouse works by reading from it
112- try :
113- # Try to read some data with a short timeout
114- data = device .read (self .in_endpoint , self .buf , timeout = 100 )
115- print (f"Mouse test read successful: { data } bytes" )
116- return True
117- except usb .core .USBTimeoutError :
118- # Timeout is normal if mouse isn't moving
119- print ("Mouse connected but not sending data (normal)" )
120- return True
121- except Exception as e : # pylint: disable=broad-except
122- print (f"Mouse test read failed: { e } " )
123- # Continue to try next device or retry
124- self .mouse = None
125- self .in_endpoint = None
126- continue
127-
128- except Exception as e : # pylint: disable=broad-except
129- print (f"Error initializing device: { e } " )
130- continue
131-
132- if not devices_found :
133- print ("No USB devices found" )
134-
135- # If we get here without returning, no suitable mouse was found
136- print (f"No working mouse found on attempt { attempt + 1 } , retrying..." )
137- gc .collect ()
138- time .sleep (RETRY_DELAY )
139-
140- except Exception as e : # pylint: disable=broad-except
141- print (f"Error during mouse detection: { e } " )
142- gc .collect ()
143- time .sleep (RETRY_DELAY )
144-
145- print ("Failed to find a working mouse after multiple attempts" )
146- return False
147-
148- def process_mouse_input (self ):
149- """Process mouse input - simplified version without wheel support"""
150- try :
151- # Attempt to read data from the mouse (10ms timeout)
152- count = self .mouse .read (self .in_endpoint , self .buf , timeout = 10 )
153-
154- if count >= 3 : # We need at least buttons, X and Y
155- # Extract mouse button states
156- buttons = self .buf [0 ]
157- x = self .buf [1 ]
158- y = self .buf [2 ]
159-
160- # Convert to signed values if needed
161- if x > 127 :
162- x = x - 256
163- if y > 127 :
164- y = y - 256
165-
166- # Extract button states
167- current_left_button_state = buttons & 0x01
168- current_right_button_state = (buttons & 0x02 ) >> 1
169-
170- # Detect button presses
171- if current_left_button_state == 1 and self .last_left_button_state == 0 :
172- self .left_button_pressed = True
173- else :
174- self .left_button_pressed = False
175-
176- if current_right_button_state == 1 and self .last_right_button_state == 0 :
177- self .right_button_pressed = True
178- else :
179- self .right_button_pressed = False
180-
181- # Update button states
182- self .last_left_button_state = current_left_button_state
183- self .last_right_button_state = current_right_button_state
184-
185- # Update position
186- self .mouse_x += x
187- self .mouse_y += y
188-
189- # Ensure position stays within bounds
190- self .mouse_x = max (0 , min (self .SCREEN_WIDTH - 1 , self .mouse_x ))
191- self .mouse_y = max (0 , min (self .SCREEN_HEIGHT - 1 , self .mouse_y ))
192-
193- return True
194-
40+ self .mouse = find_and_init_boot_mouse ()
41+ if self .mouse is None :
42+ print ("Failed to find a working mouse after multiple attempts" )
19543 return False
19644
197- except usb .core .USBError as e :
198- # Handle timeouts silently
199- if e .errno == 110 : # Operation timed out
200- return False
45+ # Change the mouse resolution so it's not too sensitive
46+ self .mouse .display_size = \
47+ (self .SCREEN_WIDTH * self .sensitivity , self .SCREEN_HEIGHT * self .sensitivity )
20148
202- # Handle disconnections
203- if e .errno == 19 : # No such device
204- print ("Mouse disconnected" )
205- self .mouse = None
206- self .in_endpoint = None
207- gc .collect ()
49+ return True
20850
209- return False
210- except Exception as e : # pylint: disable=broad-except
211- print (f"Error reading mouse: { type (e ).__name__ } " )
212- return False
51+ def process_mouse_input (self ):
52+ """Process mouse input - simplified version without wheel support"""
53+ buttons = self .mouse .update ()
54+
55+ # Extract button states
56+ if buttons is None :
57+ current_left_button_state = 0
58+ current_right_button_state = 0
59+ else :
60+ current_left_button_state = 1 if 'left' in buttons else 0
61+ current_right_button_state = 1 if 'right' in buttons else 0
62+
63+ # Detect button presses
64+ if current_left_button_state == 1 and self .last_left_button_state == 0 :
65+ self .left_button_pressed = True
66+ else :
67+ self .left_button_pressed = False
68+
69+ if current_right_button_state == 1 and self .last_right_button_state == 0 :
70+ self .right_button_pressed = True
71+ else :
72+ self .right_button_pressed = False
73+
74+ # Update button states
75+ self .last_left_button_state = current_left_button_state
76+ self .last_right_button_state = current_right_button_state
77+
78+ # Update position
79+ self .mouse_x = self .mouse .x // self .sensitivity
80+ self .mouse_y = self .mouse .y // self .sensitivity
81+
82+ # Ensure position stays within bounds
83+ self .mouse_x = max (0 , min (self .SCREEN_WIDTH - 1 , self .mouse_x ))
84+ self .mouse_y = max (0 , min (self .SCREEN_HEIGHT - 1 , self .mouse_y ))
85+
86+ return True
21387
21488 def point_in_rect (self , x , y , rect_x , rect_y , rect_width , rect_height ):
21589 """Check if a point is inside a rectangle"""
0 commit comments