-
Notifications
You must be signed in to change notification settings - Fork 0
/
keyboard_handler.py
82 lines (64 loc) · 1.83 KB
/
keyboard_handler.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
"""
Handles I/O for quitting the server/client programs.
Uses basic synchronization techniques to demonstrate how they work in Python. Not required because of the Global Interpretor Lock (GIL).
On the use of `blocking=True`, we are using the spinlock paradigm. Look into the linux kernel if you're interested.
Also uses `global` variables which is BAD practice! Use a class to encapsulate all the state.
October 12th 2023
Eric Roth
"""
import threading
from threading import Thread
from sshkeyboard import listen_keyboard, stop_listening
# Global state
quit_thread: Thread = None
quit_lock = threading.Lock()
quit = 0
def get_quit():
"""
Allows other files to access the quit variable (w/ necessary synchronization)
"""
global quit
quit_lock.acquire(blocking=True)
ret = quit
quit_lock.release()
return ret
def on_key_press(key):
"""
Handler for pressing a key on the keyboard
"""
global quit
# Check if `enter` character is pressed
if key == '`':
quit_lock.acquire(blocking=True)
quit = 1
quit_lock.release()
def on_key_release(key):
"""
Handler for releasing a key on the keyboard
"""
return
def initialize_keyboard():
"""
Initializes the keyboard thread
"""
global quit_thread
quit_thread = Thread(target=listen_keyboard, daemon=True, kwargs={"on_press": on_key_press, "on_release": on_key_release, "sleep": 0.01})
quit_thread.start()
def destroy_keyboard():
"""
Cleans up the keyboard
"""
global quit_thread
stop_listening()
quit_thread.join()
if __name__ == "__main__":
"""
Sample program which demonstartes use of the keyboard handler.
"""
initialize_keyboard()
while True:
q = get_quit()
if q:
break
destroy_keyboard()
print("Quit the program!")